64位Python中的MemoryError?

时间:2018-08-24 17:37:22

标签: python python-3.x memory out-of-memory

我在Linux上运行64位Python 3,并且我有一个代码可以生成包含约20,000个元素的列表。当我的代码尝试通过pickle模块将大约20,000个2D数组的列表写入二进制文件时,发生了内存错误,但是它生成了所有这些数组并将它们附加到此列表中,而没有出现问题。我知道这必须占用大量内存,但是我正在使用的计算机大约有100GB的可用空间(来自命令free -m)。出现错误的行:

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

其中data是我约20,000个numpy数组的列表。另外,以前我试图用大约55,000个元素来运行此代码,但是尽管将所有数组追加到data列表的过程中占了40%的时间,但是它只是单独输出Killed。所以现在我试图将其分成多个部分,但是这次我遇到了MemoryError。我该如何绕过呢?我还被告知可以访问多个CPU,但是我不知道如何利用这些CPU(我还不了解multiprocessing)。

1 个答案:

答案 0 :(得分:0)

Pickle将尝试解析所有数据,并可能在将所有内容写入磁盘之前将其转换为中间状态-因此,如果您使用的可用内存大约为一半,它将消耗up尽。

由于您的数据已在列表中,因此一种简单的解决方法是对每个数组进行腌制并存储,而不是尝试一次执行序列化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

之所以可行,是因为从文件中取消拾取的行为表现得非常好:文件指针恰好停留在文件中存储的腌制对象结束的位置-因此,进一步的读取从下一个对象的开头开始。