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__)
,没有观察到泄漏。
更新:简化代码以突出问题。
最佳答案
没有泄漏! 引用: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 A list of objects which the collector found to be unreachable but could not be freed (uncollectable objects).
我假设:
- 循环引用是不可访问的,但可以被释放,因此可以被收集。
__del__
终结器(带有循环引用?)对象无法访问且无法释放,因此无法回收。
关于python - json.dumps 会泄漏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47309117/