python - 为什么将 python 'shelve' 转换为 'dict' 使用这么多内存?

标签 python memory ipython shelve

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

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

谁能解释一下?也许提供一个潜在的解决方法?

编辑:使用 Python 2.7

最佳答案

根据我的经验,我认为酸洗比您目前所做的更耗费内存。但是,创建一个 dict 会立即将 shelf 中的每个键和值加载到内存中,您不应该假设因为您的 shelf 在磁盘上有 6GB,所以它在内存中只有 6GB。例如:

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

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

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

关于python - 为什么将 python 'shelve' 转换为 'dict' 使用这么多内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28204603/

相关文章:

python - matplotlib close 不关闭窗口

python - 如何获取两个日期之间的所有星期?

c++ - 什么是地址 0xbaddc0dedeadbead "Bad decode dead bead"

python - 为什么 Jupyter Notebook 在制作更新图时会创建重复图

python - 更改数据帧索引后的 pandas 版本 0.16.0 所有值都变为 NaN

python - C Python API Extensions 忽略了 open(errors ="ignore") 并一直抛出编码异常

python - 将 Twitter 时间转换为特定格式的日期时间,以统计一天中推文的频率

objective-c - 如何在内存中存储分子?

objective-c - Objective-C - 弹出 UITableViewController 场景时不释放内存

python - 定义一个 IPython 魔法来替换下一个单元格的内容