Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
内存泄漏Python,列出内部for循环_Python_Python 3.x_Memory Leaks - Fatal编程技术网

内存泄漏Python,列出内部for循环

内存泄漏Python,列出内部for循环,python,python-3.x,memory-leaks,Python,Python 3.x,Memory Leaks,我编写了一个简单的代码片段来处理一个文本文件,该文件每行包含一个带有词性标记的单词(例如I/noun am/verb),我想分别提取单词和标记: splitted_sentences = [] splitted_pos = [] with open("my_path", "r") as tagged_sentences: for sentence in tagged_sentences: curr_sentence = [] curr_pos = []

我编写了一个简单的代码片段来处理一个文本文件,该文件每行包含一个带有词性标记的单词(例如I/noun am/verb),我想分别提取单词和标记:

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)

代码按预期工作,但当循环执行时,内存ram消耗从未停止增加,远远高于预期(文本文件约为100MB,ram达到5GB的峰值消耗)。我尝试过使用一些内存分析工具,看起来我正在创建数千个列表引用(可能是curr_语句和curr_pos列表)。在不发生内存泄漏的情况下,解决此问题的正确方法是什么?

拆分句子是字符串列表。列表的内存开销约为70字节,字符串的内存开销约为40字节。假设平均单词/词组为5字节,平均句子为10个单词/词组对,如果所有字符串都是唯一的,则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()]

拆分句子
是字符串列表。列表的内存开销约为70字节,字符串的内存开销约为40字节。假设平均单词/词组为5字节,平均句子为10个单词/词组对,如果所有字符串都是唯一的,则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_语句和curr_pos移到for循环之外。然后可以清除,而不是创建新的。我的猜测是,出于某种原因,curr_语句和curr_pos列表没有在for循环的末尾被删除


通过将这些列表移到for循环之外,您不会在每次迭代中创建新的列表。

将curr\u语句和curr\u pos移到for循环之外。然后可以清除,而不是创建新的。我的猜测是,出于某种原因,curr_语句和curr_pos列表没有在for循环的末尾被删除


通过将这些列表移到for循环之外,您不会在每次迭代中创建新的列表。

使用非常小的文件(例如3个句子)运行它。使用调试器逐行检查每一行并查看变量内容。使用像PyCharm这样的真正的IDE。您可以检查
枚举(带标记的句子)
以了解内存在您的行中增长的速度。这就是全部代码吗?这一部分似乎是正确的,不应该产生这样的问题——而且,您的文本文件格式是否正确?没有“/”或“”的较大部分也可能会困扰此代码段。请使用非常小的文件(例如3个句子)运行它。使用调试器逐行检查每一行并查看变量内容。使用像PyCharm这样的真正的IDE。您可以检查
枚举(带标记的句子)
以了解内存在您的行中增长的速度。这就是全部代码吗?这一部分似乎是正确的,不应该产生这样的问题——而且,您的文本文件格式是否正确?大量没有“/”或“”的食物也会给这个片段带来麻烦。马拉特的答案看起来比我的好。:)马拉的答案看起来比我的好。:)