繁体   English   中英

内存泄漏Python,在for循环中列出

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM