在Python中将数据进行pickle时出现了MemoryError

7

我正在尝试使用python中提供的“dump”命令将一个字典转换为pickle格式。该字典文件大小约为150MB,但是当只dump了115MB的内容时,就会出现异常。异常如下:

Traceback (most recent call last): 
  File "C:\Python27\generate_traffic_pattern.py", line 32, in <module> 
    b.dump_data(way_id_data,'way_id_data.pickle') 
  File "C:\Python27\class_dump_load_data.py", line 8, in dump_data 
    pickle.dump(data,saved_file) 
  File "C:\Python27\lib\pickle.py", line 1370, in dump 
    Pickler(file, protocol).dump(obj) 
  File "C:\Python27\lib\pickle.py", line 224, in dump 
    self.save(obj) 
  File "C:\Python27\lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
  File "C:\Python27\lib\pickle.py", line 649, in save_dict 
    self._batch_setitems(obj.iteritems()) 
  File "C:\Python27\lib\pickle.py", line 663, in _batch_setitems 
    save(v) 
  File "C:\Python27\lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
  File "C:\Python27\lib\pickle.py", line 600, in save_list 
    self._batch_appends(iter(obj)) 
  File "C:\Python27\lib\pickle.py", line 615, in _batch_appends 
    save(x) 
  File "C:\Python27\lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
  File "C:\Python27\lib\pickle.py", line 599, in save_list 
    self.memoize(obj) 
  File "C:\Python27\lib\pickle.py", line 247, in memoize 
    self.memo[id(obj)] = memo_len, obj 
MemoryError

我真的很困惑,因为我的代码之前还能正常工作。


2
这与Pickle无关。Python正在请求更多的内存来存储一些对象,但操作系统告诉Python该进程没有更多可用的内存。这个错误可能发生在你代码的任何地方。 - Martijn Pieters
如何解决这个问题?以及之前它是如何工作的? - tanzil
1
在进行数据序列化时,同一个循环会根据需要不断创建对象,因此可能会在同一位置触发相同的异常。显然,在您的计算机上早些时候有更多的可用内存,或者您的Python会话在其他位置使用的内存较少,并且没有达到操作系统设置的限制。 - Martijn Pieters
3
如果这是你的脚本的系统性问题,你可以选择增加内存、解除操作系统的单进程限制(例如使用 ulimit )或者对应用程序的内存使用情况进行分析(参见哪个Python内存分析器推荐?)。 - Martijn Pieters
我不是很了解Windows XP,我认为默认情况下没有每个进程的限制,或者你可以进行微调。这样只留下两种选择:“获取更多内存”(通过添加物理内存或关闭其他程序以释放更多内存)和“分析你的应用程序”。 - Martijn Pieters
显示剩余3条评论
2个回答

3

你试过这个吗?

import cPickle as pickle
p = pickle.Pickler(open("temp.p","wb")) 
p.fast = True 
p.dump(d) # d is your dictionary

这对我很有帮助。如果您确定每个对象只被引用一次,它可以显著减少内存占用。 - Luca Citi
嘿@richie,如何加载它,以便在加载腌制文件时不会导致内存错误? - Amarpreet Singh
为什么这个可以工作? - Stefan

3

你只是想转储一个对象,是这样吗?

如果你多次调用dump函数,那么在转储之间调用Pickler.clear_memo()将会清除内部存储的反向引用(导致“泄漏”)。这样你的代码就可以正常运行了...


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