[英]Memory leak Python, lists inside for loop
我编写了一个简单的代码段来处理一个文本文件,该文件每行包含一个带有PoS标记词(例如I /名词am /动词)的短语,我想分别提取该词和标记:
splitted_sentences = []
splitted_pos = []
with open("my_path", "r") as tagged_sentences:
for sentence in tagged_sentences:
curr_sentence = []
curr_pos = []
for tag in sentence.strip().split(" "):
splitted_tag = tag.split("/")
word = splitted_tag[0]
pos = splitted_tag[1]
curr_sentence.append(word)
curr_pos.append(pos)
splitted_sentences.append(curr_sentence)
splitted_pos.append(curr_pos)
该代码可以按预期工作,但是,在循环执行的过程中,内存的内存消耗不会停止增加,而内存的消耗远远超过预期(文本文件约为100MB,RAM的峰值消耗为5GB)。 我尝试使用一些内存分析工具,似乎正在创建数千个列表引用(可能是curr_sentence和curr_pos列表)。 解决此问题而导致内存泄漏的正确方法是什么?
splitted_sentences
是字符串列表的列表。 列表的内存开销约为70字节,字符串约为40字节。 假设平均单词/ POS为5个字节,平均句子为10个单词/ pos对,则100MB文件为1M句子* 10个单词* 1个字符串=(1M * 70)*(10 * 40)= 28Gb的内存(如果所有字符串都是唯一的) 。 显然,其中许多不是,但是可以解释这种内存消耗而不会导致内存泄漏。
我对这个问题的处理方法是顺序处理。 我怀疑您是否真的需要同时将所有这些数据存储在内存中。 用生成器替换主循环可能会改变游戏规则:
def sentence_gen(fname):
for sentence in open(fname, 'r'):
yield [pair.split("/", 1) for pair in sentence.strip().split()]
将curr_sentence和curr_pos移出for循环。 然后,您可以清除而不是创建新的。 我的猜测是,由于某种原因,curr_sentence和curr_pos列表不会在for循环的末尾删除。
通过将这些列表移到for循环之外,您将不会在每次迭代中创建新的列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.