2017-01-30 9 views
2

Я хотел бы загрузить столько данных, сколько безопасно, чтобы текущий процесс работал нормально, а также другой процесс. Я бы предпочел использовать только ОЗУ (не используя swap), но любые предложения приветствуются. Излишние данные могут быть отброшены. Каков правильный способ сделать это? Если я просто жду MemoryException, система станет неработоспособной (если используется список).Как использовать всю доступную память

data_storage = [] 
for data in read_next_data(): 
    data_storage.append(data) 

Данные, наконец, загружаются в массив numpy.

+0

Предполагая, что вы используете Linux, вы, вероятно, будете в порядке, его хорошие и ионизированные значения будут очень плохой и загружать все, что вам нравится. – ti7

ответ

4

psutil имеет virtual_memory функцию, которая содержит, помимо прочего, атрибут, представляющий свободную память:

>>> psutil.virtual_memory() 
svmem(total=4170924032, available=1743937536, percent=58.2, used=2426986496, free=1743937536) 

>>> psutil.virtual_memory().free 
1743937536 

Это должно быть очень точным (но вызов функции является дорогостоящим -slow- по крайней мере на Windows). В MemoryError не учитывается память, используемая другими учетными записями, поэтому она поднимается только в том случае, если память массива превышает общую доступную (бесплатную или нет) ОЗУ.

Возможно, вам придется угадать, в какой момент вы перестанете накапливаться, поскольку свободная память может меняться (другие процессы также требуют некоторую дополнительную память время от времени), а преобразование в numpy.array может временно удвоить используемую память, поскольку в то время список, и массив должен вписаться в вашу оперативную память.


Однако вы можете подойти к этому также по-разному:

  • Читайте в первого набора данных: read_next_data().
  • Вычислить свободную память в этой точке: psutil.virtual_memory().free
  • Используйте shape первого набора данных и dtype вычислить форму массива, который легко помещается в ОЗУ. Предположим, он использует factor (т. Е. 75%) доступной свободной памяти: rows= freeMemory * factor/(firstDataShape * memoryPerElement), которая должна дать вам количество наборов данных, которые вы читаете сразу.
  • Создайте массив этой формы: arr = np.empty((rows, *firstShape), dtype=firstDtype).
  • Загрузите следующие наборы данных, но сохраните их непосредственно в своем массиве arr[i] = next(read_next_data). Таким образом, вы не держите эти списки, и вы избегаете удвоенной памяти.