内存泄漏Python,列出内部for循环
我编写了一个简单的代码片段来处理一个文本文件,该文件每行包含一个带有词性标记的单词(例如I/noun am/verb),我想分别提取单词和标记:内存泄漏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 = []
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。您可以检查枚举(带标记的句子)
以了解内存在您的行中增长的速度。这就是全部代码吗?这一部分似乎是正确的,不应该产生这样的问题——而且,您的文本文件格式是否正确?大量没有“/”或“”的食物也会给这个片段带来麻烦。马拉特的答案看起来比我的好。:)马拉的答案看起来比我的好。:)