为什么将 Python 'shelve'转换为'dict'会占用如此多的内存?



我有一个非常大的python搁架对象(磁盘上有6GB)。我希望能够将其移动到另一台机器上,并且由于架子不便携,因此我想cPickle它。为此,我首先必须将其转换为字典。

出于某种原因,当我dict(myShelf) ipython 进程峰值高达 32GB 的内存(我所有的机器都有),然后似乎挂起(或者可能需要很长时间)。

有人可以解释一下吗?也许提供一种潜在的解决方法?

编辑:使用Python 2.7

根据我的经验,我希望腌制比你迄今为止所做的更能消耗记忆。但是,创建dict会立即将磁盘架中的每个键和值加载到内存中,您不应该因为磁盘架上有 6GB 就假设它只有 6GB 的内存。例如:

>>> import sys, pickle
>>> sys.getsizeof(1)
24
>>> len(pickle.dumps(1))
4
>>> len(pickle.dumps(1, -1))
5

因此,一个非常小的整数作为 Python int对象(在我的机器上)比它曾经被腌制时大 5-6 倍。

至于解决方法:您可以将多个腌制对象写入一个文件。因此,不要将工具架转换为dict,只需将一长串键和值写入文件,然后在另一侧读取同样长的键和值序列以放入新架子中。这样,您一次只需要内存中的一个键/值对。像这样:

写:

with open('myshelf.pkl', 'wb') as outfile:
    pickle.dump(len(myShelf), outfile)
    for p in myShelf.iteritems():
        pickle.dump(p, outfile)

读:

with open('myshelf.pkl', 'rb') as infile:
    for _ in xrange(pickle.load(infile)):
        k, v = pickle.load(infile)
        myShelf[k] = v

我认为您实际上不需要存储长度,您可以继续阅读,直到pickle.load抛出异常,指示文件已用完。

最新更新