gpt4 book ai didi

大数据结构(列表、字典)中的 Python 内存泄漏——可能是什么原因?

转载 作者:太空狗 更新时间:2023-10-29 23:59:40 26 4
gpt4 key购买 nike

代码非常简单。它不应该有任何泄漏,因为所有操作都在 函数内部 完成。并且什么都没有返回。我有一个函数遍历文件中的所有行 (~20 MiB) 并将它们全部放入列表中。
提到的功能:

def read_art_file(filename, path_to_dir):
import codecs
corpus = []
corpus_file = codecs.open(path_to_dir + filename, 'r', 'iso-8859-15')
newline = corpus_file.readline().strip()
while newline != '':
# we put into @article a @newline of file and some other info
# (i left those lists blank for readability)
article = [newline, [], [], [], [], [], [], [], [], [], [], [], []]
corpus.append(article)
del newline
del article
newline = corpus_file.readline().strip()
memory_usage('inside function')
for article in corpus:
for word in article:
del word
del article
del corpus
corpus_file.close()
memory_usage('inside: after corp deleted')
return

主要代码如下:

memory_usage('START')
path_to_dir = '/home/soshial/internship/training_data/parser_output/'
read_art_file('accounting.n.txt.wpr.art', path_to_dir)
memory_usage('outside func')
time.sleep(5)
memory_usage('END')

所有 memory_usage 只打印脚本分配的 KiB 数量。

执行脚本

如果我运行脚本,它会给我:

START memory: 6088 KiB
inside memory: 393752 KiB (20 MiB file + lists occupy 400 MiB)
inside: after corp deleted memory: 43360 KiB
outside func memory: 34300 KiB (34300-6088= 28 MiB leaked)
FINISH memory: 34300 KiB

不使用列表执行

如果我绝对做同样的事情,但将 article 附加到 corpus 注释掉:

article = [newline, [], [], [], [], [], ...]  # we still assign data to `article`
# corpus.append(article) # we don't have this string during second execution

这种方式输出给我:

START memory: 6076 KiB
inside memory: 6076 KiB
inside: after corp deleted memory: 6076 KiB
outside func memory: 6076 KiB
FINISH memory: 6076 KiB

问题:

因此,通过这种方式释放所有内存。我需要释放所有内存,因为我要处理数百个这样的文件。
是我做错了什么还是 CPython 解释器错误?

更新。这是我检查内存消耗的方式(取自其他一些 stackoverflow 问题):

def memory_usage(text = ''):
"""Memory usage of the current process in kilobytes."""
status = None
result = {'peak': 0, 'rss': 0}
try:
# This will only work on systems with a /proc file system
# (like Linux).
status = open('/proc/self/status')
for line in status:
parts = line.split()
key = parts[0][2:-1].lower()
if key in result:
result[key] = int(parts[1])
finally:
if status is not None:
status.close()
print('>', text, 'memory:', result['rss'], 'KiB ')
return

最佳答案

请注意,python 从不保证您的代码使用的任何内存实际上都会返回给操作系统。垃圾收集所保证的是,已收集的对象所使用的内存在未来的某个时间可以免费供另一个对象使用。

根据我所读1 关于内存分配器的 Cpython 实现的内容,内存在“池”中分配以提高效率。当一个池已满时,python 将分配一个新池。如果一个池只包含死对象,Cpython 实际上会释放与该池关联的内存,否则它不会。这可能会导致多个部分满的池在一个函数或其他任何东西之后徘徊。但是,这并不真正意味着它是“内存泄漏”。 (Cpython 仍然知道内存并可能在稍后释放它)。

1我不是 python 开发人员,因此这些细节可能不正确或至少不完整

关于大数据结构(列表、字典)中的 Python 内存泄漏——可能是什么原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16423176/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com