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

时间:2015-01-28 23:47:26

标签: python memory ipython shelve

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

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

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

编辑:使用Python 2.7

1 个答案:

答案 0 :(得分:4)

根据我的经验,我认为酸洗比你迄今为止所做的更重要。但是,创建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倍,而不是曾经被腌制的对象。

至于解决方法:您可以将多个pickle对象写入文件。因此,不要将货架转换为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抛出一个异常表明它已用完文件。