Python загружает 2 ГБ текстового файла в память

В Python 2.7, когда я загружаю все данные из текстового файла объемом 2,5 ГБ в память для более быстрой обработки, например:

>>> f = open('dump.xml','r')
>>> dump = f.read()

Я получил следующую ошибку:

Python(62813) malloc: *** mmap(size=140521659486208) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError

Почему Python пытается выделить140521659486208 память байтов для2563749237 байтовые данные? Как мне исправить код, чтобы он загружал все байты?

У меня свободно около 3 ГБ ОЗУ. Этот файл является дампом Wiktionary XML.

 joslinm22 июн. 2012 г., 17:22
Сколько баран? 64 или 32 бит?
 pckben22 июн. 2012 г., 17:21
Я попробовал это, и это заняло у меня очень много времени. И так как у меня много оперативной памяти, я хочу загрузить все в оперативную память, чтобы сделать ее быстрее.
 Alfe22 июн. 2012 г., 17:17
Почему вы не анализируете XML линейно, не загружая сначала источник в память?
 A-B-B22 июн. 2012 г., 18:34
Я предлагаю использовать xml ElementTree вместо SAX. Никому, кроме вас, не понравится ваше решение для регулярных выражений.
 Tim Pietzcker22 июн. 2012 г., 17:32
Вот это да. 128 терабайт? Это амбициозно изmalloc().

Ответы на вопрос(2)

Решение Вопроса

ММАПвы сможете сразу загрузить весь файл в память.

import mmap

with open('dump.xml', 'rb') as f:
  # Size 0 will read the ENTIRE file into memory!
  m = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) #File is open read-only

  # Proceed with your code here -- note the file is already in memory
  # so "readine" here will be as fast as could be
  data = m.readline()
  while data:
    # Do stuff
    data = m.readline()
 22 июн. 2012 г., 18:01
Хороший ответ, если вам действительно нужно полностью прочитать содержимое файла. В этом случае я не думаю, что это лучшее решение для ситуации pckben.
 pckben22 июн. 2012 г., 17:42
я получилmmap.error: [Errno 13] Permission denied для линии сm = mmap.mmap(..)как это исправить?
 22 июн. 2012 г., 17:49
@pckben Это потому, что файл открыт в режиме только для чтения и mmap попытается отобразить чтение-запись: добавитьprot=mmap.PROT_READ в вашемmmap.mmap позвони, и ты будешь в порядке.
 pckben22 июн. 2012 г., 18:00
Здорово. Это сработало! Не могли бы вы объяснить, что случилось?
 22 июн. 2012 г., 18:03
mmap - это отображение памяти файла. Получив доступ к памяти в выделенном месте, вы получите доступ к файлу. Независимо от того, буферизует ли ОС весь файл заранее или только при доступе, это часть конфигурации ;-)

это сообщение на форуме кажется, это решает проблему, с которой вы, похоже, столкнулись. Предполагая, что вы используете Mac или Linux на основе кода ошибки, вы можете попробовать реализовать сборку мусора с помощьюgc.enable() или жеgc.collect() как предложено в сообщении на форуме.

 pckben22 июн. 2012 г., 17:30
мой код состоит всего из двух строк для загрузки данных в память, другого живого объекта для сборки мусора нет.

Ваш ответ на вопрос