为什么转换python';货架';至';dict';使用这么多内存?

为什么转换python';货架';至';dict';使用这么多内存?,python,memory,ipython,shelve,Python,Memory,Ipython,Shelve,我有一个非常大的python搁置对象(磁盘上有6GB)。我想把它移到另一台机器上,因为架子是不可移动的,所以我想把它打包。要做到这一点,我首先要把它转换成dict 出于某种原因,当我执行dict(myShelf)时,ipython进程会占用32GB的内存(我的机器所有的内存),然后似乎会挂起(或者可能需要很长时间) 有人能解释一下吗?也许能提供一个潜在的解决办法 编辑:根据我的经验,使用Python2.7时,我希望pickle比您目前所做的更占用内存。但是,创建一个dict会立即将工具架中的每个

我有一个非常大的python搁置对象(磁盘上有6GB)。我想把它移到另一台机器上,因为架子是不可移动的,所以我想把它打包。要做到这一点,我首先要把它转换成dict

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

有人能解释一下吗?也许能提供一个潜在的解决办法


编辑:根据我的经验,使用Python2.7时,我希望pickle比您目前所做的更占用内存。但是,创建一个
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过的值

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

写:

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


我想您实际上不需要存储长度,您可以一直读取,直到
pickle.load
抛出一个异常,表明它的文件已用完。

您的意思是迭代书架吗?我的意思是在myShelf.items()中对k,v使用
(或者在Python 2中使用
iteritems
)+1转换为
dict
,您以数据结构的内部簿记的形式增加了内存开销。这是一个非常好的主意。@uʍopǝpısdn:更重要的是,当转换为
dict
时,所有内容都需要立即存储在内存中。即使有足够的交换来处理,也不太好。难以置信的是,对于一个dict来说,它会有如此多的开销(超过内容的4倍)。它应该只是一个哈希表,对吗?
with open('myshelf.pkl', 'rb') as infile:
    for _ in xrange(pickle.load(infile)):
        k, v = pickle.load(infile)
        myShelf[k] = v