尽管垃圾收集,Python内存仍在增加

时间:2018-03-19 18:14:02

标签: python memory garbage-collection out-of-memory

我尝试使用类似MapReduce的方式使用多个线程来计算大型文档池中大量单词的出现。每个线程都以一个字典开始,该字典将语料库中的每个单词映射为零,并在计数越过文档时递增计数。一旦完成所有线程,我想累积计数。我将第一个json文件加载到内存中并循环遍历其余部分,总结计数:

setUp()

此处collectstatic是包含所有最终计数的最终字典。 def merge_counts(self): path = os.path.join(self.get_current_job_directory(), 'batch_0.json') with open (path, 'r') as json_file: kmers = json.load(json_file) batch = None for i in range(1, self.num_threads): path = os.path.join(self.get_current_job_directory(), 'batch_' + str(i) + '.json') with open (path, 'r') as json_file: batch = json.load(json_file) for kmer in batch: kmers[kmer] += batch[kmer] batch = None return kmers 内的密钥数量无论加载多少个批次都保持不变,因为它们只有不同的计数才具有相同的密钥。每个json文件大约3 gig,所以最终结果也大致相同。我希望这段代码能够使用尽可能多的内存,就像在内存中保存两个这样的json文件(迄今为止的共识和当前批处理)作为字典,但内存使用量随每个批量线性增长,直到我最终耗尽内存。为什么会这样?当我将它设置为kmers时,变量kmers引用的先前的东西是不是被垃圾收集了?

更新:所以我在每次循环迭代结束时添加了batch,内存在每次迭代时仍然呈线性增长。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我确定您现在已经解决了这个问题,但是最近我遇到了类似的问题,而且很难找到答案。因此,在此处发布我的解决方案以作记录。

大型文件上的json.load()(或loads())似乎可以防止batch由于某些引用而被垃圾回收,从而导致大量内存泄漏。

不过,使batch成为json.load()的深层副本似乎允许python正确运行垃圾回收。所以:

import copy
...
batch = copy.deepcopy(json.load(json_file))
...
gc.collect()

还没来得及研究为什么会发生这种情况,但是对于我来说似乎是可行的。