Python搁置OutOfMemory错误

fsm*_*fsm 2 python persistence dictionary shelve out-of-memory

我有一些数据存储在我想要处理的数据库中.数据库访问非常缓慢,因此我决定在进行任何处理之前将所有数据加载到字典中.但是,由于存储的数据量巨大,我得到了一个内存不足的错误(我看到使用了超过2个演出).所以我决定使用磁盘数据结构,并发现使用shelve是一种选择.这是我做的(伪python代码)

def loadData():
    if (#dict exists on disk):
        d = shelve.open(name)
        return d
    else:
        d = shelve.open(name, writeback=True)
        #access DB and write data to dict
        # d[key] = value 
        # or for mutable values
        # oldValue = d[key]
        # newValue = f(oldValue)
        # d[key] = newValue 
        d.close()
        d = shelve.open(name, writeback=True)
        return d
Run Code Online (Sandbox Code Playgroud)

我有一些问题,

1)我真的需要writeBack = True吗?它有什么作用?

2)我仍然得到一个OutofMemory异常,因为我没有对数据写入磁盘的时间进行任何控制.我怎么做?我尝试每隔几次迭代执行一次sync(),但这也无济于事.

谢谢!

Ale*_*lli 10

writeback=True强制搁架在内存中保留任何已取出的物品,并在搁架关闭时将其写回.因此,它消耗更多内存,并减慢关闭速度.

该参数的优点在于,使用它,您不需要在注释中显示的变形代码,其中mutator是一个方法的可变项 - 只是

shelf['foobar'].append(23)
Run Code Online (Sandbox Code Playgroud)

工作(如果shelf在启用了写回的情况下打开),假设key 'foobar'处的项目是一个当然列表,而它将默认为无操作(如果shelf在没有写回的情况下打开磁盘上的项目)- 在后一种情况下你实际上确实需要编码

thelist = shelf['foobar']
thelist.append(23)
shekf['foobar'] = thelist
Run Code Online (Sandbox Code Playgroud)

在你的评论的精神 - 这在风格上有点令人失望.

不过,既然你有记忆的问题,我绝对推荐使用该可疑写回选项.我认为我可以称之为"可疑",因为我是那个提议并首次实施它的人,但那是多年前的事情,而且我大部分时间都在悔改 - 它产生了更多的混乱(作为你的Q证据)而不是它允许优雅和轻松移动最初编写的代码以使用dicts(这将使用第一个成语,而不是第二个,因此需要重写以便可以在没有回溯的情况下使用架子).好吧,对不起,当时这似乎是个好主意.

  • @Steven,每个`sync`都会清空架子的缓存,所以如果你经常这样做就可以改善内存压力(整体速度问题会一样糟糕,或者更糟,但是会扩散到所有`sync`调用而不是集中在最后"关闭" - 这种传播效果可能是好的还是坏的,取决于). (2认同)