import gc, json
class leak(object):
def __init__(self):
pass
gc.set_debug(gc.DEBUG_LEAK)
while True:
leak_ = leak()
json.dumps(leak_.__dict__, indent=True)
gc.collect()
print(f"garbage count: {len(gc.garbage)}")
在Python 3.6.3下使用以下代码,垃圾计数不断增加,任务管理器记录稳定内存增加。
但是没有缩进json.dumps(self.__dict__)
,没有发现泄漏。
更新:简化了代码以突出显示问题。
答案 0 :(得分:1)
参考:https://bugs.python.org/issue32045
indent=True
只是让json使用Python实现而不是C实现。 Python实现使用相互引用的闭包。不涉及json的简单示例是:
import gc
def f():
def g():
return h
def h():
return g
return
gc.set_debug(gc.DEBUG_LEAK)
while True:
f()
gc.collect()
print(f"garbage count: {len(gc.garbage)}")
使用gc.set_debug(gc.DEBUG_LEAK)导致“泄漏”。 gc.DEBUG_LEAK包括gc.DEBUG_COLLECTABLE,gc.DEBUG_UNCOLLECTABLE和gc.DEBUG_SAVEALL。
gc.DEBUG_SAVEALL导致垃圾收集对象保存在gc.garbage中以供检查。在正常情况下,他们被收集。
我的回复:
你是对的。我意识到后来我实际上在一个com实例化对象中有泄漏,假设它是python中的泄漏并试图使用gc模块找到它。gc文档让我走上了花园小径。
我假设:gc.garbage收集器发现的对象列表 无法访问但无法释放(无法收集的对象)。
__del__
终结器(带有循环引用?)对象无法访问,无法释放,因此无法收集。