Python将2GB文本文件加载到内存中

12
在Python 2.7中,当我将一个大小为2.5GB的文本文件的所有数据加载到内存中以便更快地处理时,可以像这样操作:
>>> 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为什么试图为2563749237字节的数据分配140521659486208字节的内存?如何修复代码以使其加载所有字节?

我有大约3GB的可用RAM。该文件是Wiktionary的xml转储。


7
为什么不先线性解析XML而不是首先将源代码加载到内存中? - Alfe
我尝试过,但花费了很长时间。由于我有很多RAM,所以我想将所有内容加载到RAM中以使其更快。 - pckben
我在我的Mac Pro上有8GB的RAM,我认为它是64位的。 - pckben
2
哇,128 TB?这对malloc()来说是雄心勃勃的。 - Tim Pietzcker
2
我建议使用xml ElementTree而不是SAX。除了你自己,没有人会喜欢你的正则表达式解决方案。 - Asclepius
显示剩余7条评论
2个回答

13
如果你使用 mmap,你就可以立即将整个文件加载到内存中。
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()

我在使用m = mmap.mmap(..)这一行时遇到了mmap.error: [Errno 13] Permission denied的错误,我该如何解决? - pckben
2
@pckben 这是因为文件以只读模式打开,而mmap将尝试映射读写:在你的 mmap.mmap 调用中添加 prot=mmap.PROT_READ , 就可以解决问题了。 - Thomas Orozco
如果你必须完全读取文件内容,那么这是个好答案。但在这种情况下,我不认为这是pckben问题的最佳解决方案。 - Alfe
2
mmap 是文件的内存映射。在分配的位置访问内存将访问文件。操作系统是否预先缓冲整个文件或仅在访问时缓冲是配置的一部分;-) - Alfe
@pckben 使用 open('myfile', 'rb') 以只读模式打开文件,但 mmap 将尝试将其映射为读写模式,这会导致错误。 - Thomas Orozco

-1

根据一些快速的谷歌搜索,我发现了这篇论坛帖子,它似乎解决了你所遇到的问题。假设你是基于 Mac 或 Linux 运行的,根据错误代码,你可以尝试在论坛帖子中建议的使用 gc.enable()gc.collect() 来实现垃圾回收。


我的代码只有两行,用于将数据加载到内存中,没有其他存活对象进行垃圾回收。 - pckben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接