MemoryError в 64-битном Python? - PullRequest
       9

MemoryError в 64-битном Python?

0 голосов
/ 24 августа 2018

Я использую 64-битный Python 3 в Linux, и у меня есть код, который генерирует списки, содержащие около 20 000 элементов. Произошла ошибка памяти, когда мой код попытался записать список из ~ 20 000 2D-массивов в двоичный файл через модуль pickle, но он сгенерировал все эти массивы и без проблем добавил их в этот список. Я знаю, что это должно занимать много памяти, но на машине, которую я использую, доступно около 100 ГБ (из команды free -m). Строка с ошибкой:

with open('all_data.data', 'wb') as f:
    pickle.dump(data, f)
>>> MemoryError

, где data - мой список из ~ 20000 массивов. Кроме того, ранее я пытался запустить этот код с около 55 000 элементов, но хотя он был добавлен в список data, и он был на 40% завершен, он просто выводил Killed сам по себе. Так что теперь я пытаюсь разбить его на сегменты, но на этот раз я получаю MemoryError. Как я могу обойти это? Мне также сообщили, что у меня есть доступ к нескольким процессорам, но я не знаю, как ими воспользоваться (я пока не понимаю multiprocessing).

1 Ответ

0 голосов
/ 24 августа 2018

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

Поскольку ваши данные уже есть в списке, существует простой способ обойти каждый массив и сохранить его, вместо того, чтобы сериализовать 20000 массивов за один раз:

with open('all_data.data', 'wb') as f:
    for item in data:
        pickle.dump(item, f)

Затем, чтобы прочитать его, просто продолжайте извлекать объекты из файла и добавлять его в список, пока файл не будет исчерпан:

data = []
with open('all_data.data', 'rb') as f:
    while True:
        try:
            data.append(pickle.load(f))
        except EOFError:
            break

Это работает, потому что отмена выбора из файла ведется довольно хорошо: указатель файла остается точно в том месте, где заканчивается консервированный объект, сохраненный в файле - поэтому дальнейшие чтения начинаются с начала следующего объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...