关于内存:Python中的Pickle的MemoryError

MemoryError with Pickle in Python

我正在处理一些数据,并将结果存储在三个字典中,然后用pickle将它们保存到磁盘上。每本字典有500-1000MB。

现在我给它们装上:

1
2
3
import pickle
with open('dict1.txt',"rb") as myFile:
    dict1 = pickle.load(myFile)

但是,在加载第一本词典时,我已经得到了:

1
2
3
4
5
6
7
8
9
10
*** set a breakpoint in malloc_error_break to debug
python(3716,0xa08ed1d4) malloc: *** mach_vm_map(size=1048576) failed (error code=3)
*** error: can't allocate region securely
*** set a breakpoint in malloc_error_break to debug
Traceback (most recent call last):
  File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1019, in load_empty_dictionary
    self.stack.append({})
MemoryError

如何解决这个问题?我的计算机有16GB的内存,所以我发现加载800MB字典时崩溃是很不寻常的。我还发现不寻常的是保存字典时没有问题。

此外,我计划在将来处理更多的数据,从而生成更大的字典(磁盘上有3-4GB),因此,任何关于如何提高效率的建议都会受到赞赏。


如果字典中的数据是numpy数组,则有一些包(如joblibklepto使酸洗大型数组有效,因为kleptojoblib都了解如何使用numpy.array的最小状态表示。如果您没有array数据,我建议使用klepto将字典条目存储在多个文件(而不是单个文件)或数据库中。

请看我对一个非常密切相关的问题的答案https://stackoverflow.com/a/25244747/2379433,如果您可以对多个文件而不是单个文件进行酸洗,希望并行保存/加载您的数据,或者希望轻松尝试存储格式和后端,以查看哪一个最适合您的情况。另请参阅:https://stackoverflow.com/a/21948720/2379433了解其他可能的改进,这里还有:https://stackoverflow.com/a/24471659/2379433。

正如上面的链接所讨论的,您可以使用klepto,它使您能够使用通用API轻松地将字典存储到磁盘或数据库中。klepto还允许您选择存储格式(picklejson等),另外,HDF5或SQL数据库是另一个不错的选择,因为它允许并行访问。klepto可以使用专门的pickle格式(如numpy格式)和压缩(如果您关心数据的大小而不是访问速度)。

klepto为您提供了使用"一体"文件或"每个文件一个条目"存储字典的选项,还可以利用多处理或多线程——这意味着您可以并行地将字典项保存到/从后端加载。有关示例,请参见上面的链接。


这是泡菜固有的问题,用于少量的数据。字典的大小,当加载到内存中时,比磁盘大很多倍。

在加载了100MB的pickle文件之后,您可能已经一本大约1 GB的字典。网上有一些计算开销的公式,但我只能推荐使用一些像mysql或postgresql这样的数据量数据库。


我支持你使用32位的python,它有4GB的限制。您应该使用64位而不是32位。我试过了,我的腌制听写超过了1.7GB,除了时间变长之外,我没有遇到任何问题。