【发布时间】:2018-03-19 18:14:01
【问题描述】:
我正在尝试以类似 MapReduce 的方式使用多个线程来计算大量文档中大量单词的出现次数。每个线程都从一个字典开始,将语料库中的每个单词映射为零,并在遍历文档时递增计数。完成所有线程后,我想累积计数。我将第一个 json 文件加载到内存中,然后循环遍历其余文件,对计数求和:
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
这里的kmers 是包含所有最终计数的最终字典。无论加载多少批次,kmers 中的键数量都保持不变,因为它们都具有相同的键,只是计数不同。每个 json 文件大约 3 gig 大,因此最终结果也大致相同。我希望这段代码使用与在内存中保存两个这样的 json 文件(到目前为止的共识和当前批次)作为字典一样多的内存,但是内存使用量随着每个批次线性增长,直到我最终耗尽内存。为什么会这样?当我将变量batch 设置为None 时,变量batch 引用的先前内容不应该被垃圾收集吗?
更新:所以我在每次循环迭代结束时添加了gc.collect(),内存仍然随着每次迭代线性增长。有什么想法吗?
【问题讨论】:
-
你试过强制垃圾回收吗? stackoverflow.com/a/1316793/1042144
-
@BrianKung 这确实有助于阻止线性增长,但内存使用量仍会随着时间的推移而增加。
-
不幸的是,我并不是特别擅长内存管理,Python 也不是我的主要语言。也许可以围绕它进行一些检测,然后在 Python 中查找内存优化技术。祝你好运!
-
了解问题被否决的原因会很有帮助,这样我就可以增加获得有用答案的机会。
标签: python memory garbage-collection out-of-memory