Ошибки памяти и ограничения списка?

Мне нужно производить большие и большие (очень) матрицы (цепи Маркова) для научных целей. Я выполняю расчет, который помещаю в список из 20301 элемента (= одна строка моей матрицы). Мне нужны все эти данные в памяти, чтобы перейти к следующему шагу Маркова, но я могу сохранить их в другом месте (например, в файле), если необходимо, даже если это замедлит прохождение моей цепи Маркова. Мой компьютер (научная лаборатория): биксеноновый 6 ядер / 12 потоков каждый, 12 ГБ памяти, ОС: win64

  Traceback (most recent call last):
  File "my_file.py", line 247, in <module>
    ListTemp.append(calculus)
MemoryError

Пример результатов расчета: 9.233747520008198e-102 (да, больше 1/9000)

Ошибка возникает при сохранении 19766-го элемента:

ListTemp[19766]
1.4509421012263216e-103

Если я пойду дальше

Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    ListTemp[19767]
IndexError: list index out of range

Итак, в этом списке была ошибка памяти в цикле 19767 года.

Вопросов:

  1. Есть ли ограничение памяти для списка? Это ограничение по списку или глобальное ограничение по сценариям?

  2. Как обойти эти ограничения? Есть какие-нибудь возможности?

  3. Поможет ли использовать numpy, python64? Какие у них ограничения памяти? А как насчет других языков?


person Taupi    schedule 04.04.2011    source источник
comment
Если вы получаете неожиданную ошибку памяти и думаете, что у вас должно быть достаточно оперативной памяти, это может быть связано с тем, что вы используете 32-разрядную установку Python.   -  person mgoldwasser    schedule 09.06.2016
comment
Большой и большой! Ух ты! Хорошо, что у тебя столько памяти! ????   -  person Michael Scheper    schedule 22.11.2017


Ответы (4)


Прежде всего, см. Насколько большим может быть массив Python? и Numpy, проблема с длинными массивами

Во-вторых, единственное реальное ограничение - это объем памяти, который у вас есть, и то, как ваша система хранит ссылки на память. Ограничений по спискам нет, поэтому Python будет работать до тех пор, пока не закончит память. Две возможности:

  1. Если вы работаете в более старой ОС или в той, которая заставляет процессы использовать ограниченный объем памяти, вам может потребоваться увеличить объем памяти, к которой процесс Python имеет доступ.
  2. Разбейте список на части. Например, выполните первые 1000 элементов списка, выберите и сохраните их на диск, а затем выполните следующие 1000. Чтобы работать с ними, выделяйте по одному фрагменту за раз, чтобы у вас не закончилась память. По сути, это тот же метод, который базы данных используют для работы с большим объемом данных, чем умещается в ОЗУ.
person G Gordon Worley III    schedule 04.04.2011
comment
source Следовательно, максимальный размер Список python в 32-битной системе составляет 536 870 912 элементов. Хорошо, но в моем случае я далек от этого значения, моя память составляет только ~ 1,3 Гбайт для этого процесса (около предела процесса python32?) . Какой будет предел в python64? Каким образом фрагменты будут замедляться при прохождении цепочки Маркова? Спасибо @ всем за ответы и советы. Хорошее место, чтобы учиться! - person Taupi; 04.04.2011
comment
32-разрядный процесс имеет теоретический предел в 4 ГБ памяти, хотя, если ваша ОС также 32-разрядная, очевидно, что он будет меньше, поскольку ОС будет занимать часть этой памяти. Разделение на части замедлит вас, но в некоторых случаях вам придется принять замедление, чтобы закончить обработку. Что вы храните в этом списке? Может быть, это поможет объяснить, что происходит. - person G Gordon Worley III; 04.04.2011

MemoryError исключение, которое вы видите, является прямым результатом нехватки доступной оперативной памяти. Это могло быть вызвано либо ограничением в 2 ГБ на программу, установленным Windows (32-битные программы) или недостаток доступной оперативной памяти на вашем компьютере. (Эта ссылка относится к предыдущему вопросу).

Вы должны иметь возможность расширить 2 ГБ, используя 64-битную копию Python, при условии, что вы используете 64-битную копию Windows.

IndexError будет вызвано тем, что Python обнаружил исключение MemoryError перед вычислением всего массива. Опять же, это проблема памяти.

Чтобы обойти эту проблему, вы можете попробовать использовать 64-битную копию Python или, что еще лучше, найти способ записывать результаты в файл. Для этого посмотрите на массивы с отображением памяти numpy.

Вы должны иметь возможность выполнить весь набор вычислений в одном из этих массивов, поскольку фактические данные будут записаны на диск, и только небольшая их часть будет храниться в памяти.

person thomas    schedule 04.04.2011
comment
Здравствуйте, Томас, я думаю, что вы правы, я должен переполнить 2 ГБ на программу, наложенную моим python32 на мои windows-7-64b. Какой будет предел для программы python64? Благодарность - person Taupi; 04.04.2011
comment
Значительно больше, чем физическая память на вашем компьютере, поскольку вы возводите в квадрат размер адресного пространства, перейдя на 64 бита :) - person ncoghlan; 04.04.2011
comment
@ncoghlan прав. Если перейти по ссылке во второй строке, будет указан лимит. Это колоссальные 8 ТБ. Если вы достигнете этого предела, значит, вы определенно делаете что-то не так :) - person thomas; 04.04.2011

Python не накладывает ограничений на объем памяти. Однако вы получите MemoryError, если у вас закончится ОЗУ. Вы говорите, что у вас 20301 элемент в list. Это кажется слишком маленьким, чтобы вызвать ошибку памяти для простых типов данных (например, int), но если каждый элемент сам по себе является объектом, который занимает много памяти, возможно, у вас заканчивается память.

Однако IndexError, вероятно, вызван тем, что ваш ListTemp имеет только 19767 элементов (с индексами от 0 до 19766), и вы пытаетесь получить доступ после последнего элемента.

Трудно сказать, что вы можете сделать, чтобы не достичь предела, не зная точно, что именно вы пытаетесь сделать. Использование numpy может помочь. Похоже, вы храните огромное количество данных. Возможно, вам не нужно хранить все это на каждом этапе. Но этого нельзя сказать, не зная.

person MAK    schedule 04.04.2011
comment
Python, как и любая другая программа, использует всю виртуальную память, а не только физическую (RAM). Плакат может увеличить доступную память подкачки (которая представляет собой файл в Windows и раздел в Linux). - person Ricardo Magalhães Cruz; 05.01.2016
comment
Вы также можете использовать файл подкачки в Linux. Взято из Arch Wiki: # touch /swapfile # fallocate -l 512M /swapfile # dd if=/dev/zero of=/swapfile bs=1M count=512 # chmod 600 /swapfile # mkswap /swapfile # swapon /swapfile # echo "/swapfile none swap defaults 0 0" >> /etc/fstab - person copeland3300; 14.09.2016

Если вы хотите обойти эту проблему, вы также можете использовать полку. Затем вы должны создать файлы, размер которых будет соответствовать возможностям вашего компьютера, и помещать их в оперативную память только при необходимости, в основном записывая на жесткий диск и извлекая информацию обратно по частям, чтобы вы могли ее обработать.

Создайте двоичный файл и проверьте, есть ли в нем информация, если да, создайте локальную переменную для ее хранения, иначе напишите некоторые данные, которые вы сочтете необходимыми.

Data = shelve.open('File01')
   for i in range(0,100):
     Matrix_Shelve = 'Matrix' + str(i)
     if Matrix_Shelve in Data:
        Matrix_local = Data[Matrix_Shelve]
     else:
        Data[Matrix_Selve] = 'somenthingforlater'

Надеюсь, это звучит не слишком архаично.

person Eduardo Dias Florentino    schedule 30.03.2018