ale*_*cxe 7 python memory debugging garbage-collection memory-management
故事:
在Nina Zakharenko的PyCon谈论 Python内存管理期间,她解释了Python 中分代垃圾收集的工作方式,注意到:
Python维护一个程序运行时创建的每个对象的列表.实际上,它使3:
generation 0generation 1generation 2
问题:
为了更好地理解Python中的内存管理以及调试内存泄漏的目的,如何在程序运行期间观察/观察在所有3代列表中添加和删除的对象?
我查看了gc模块,但没有找到获取当前生成列表值的相关方法.
正如我们在评论中讨论的,我认为没有办法直接从 python 访问生成列表,您可以设置一些调试标志,在 python2 中您可以使用以下内容来报告可以或不能收集的对象:
import gc
gc.set_debug(gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_COLLECTABLE | gc.DEBUG_OBJECTS )
Run Code Online (Sandbox Code Playgroud)
在 python3 中,使用以下命令将为您提供一些有关可收集和不可收集对象的生成输出和信息:
import gc
gc.set_debug(gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_COLLECTABLE | gc.DEBUG_STATS)
Run Code Online (Sandbox Code Playgroud)
你会得到如下输出:
gc: collecting generation 2...
gc: objects in each generation: 265 4454 0
gc: collectable <function 0x7fad67f77b70>
gc: collectable <tuple 0x7fad67f6f710>
gc: collectable <dict 0x7fad67f0e3c8>
gc: collectable <type 0x285db78>
gc: collectable <getset_descriptor 0x7fad67f095e8>
gc: collectable <getset_descriptor 0x7fad67f09630>
gc: collectable <tuple 0x7fad67f05b88>
gc: done, 7 unreachable, 0 uncollectable, 0.0028s elapsed.
gc: collecting generation 2...
Run Code Online (Sandbox Code Playgroud)
对于根据设置的泄漏,找到的所有无法访问的对象将被附加到垃圾中而不是被释放。这对于调试泄漏程序很有用:gc.DEBUG_SAVEALL
import gc
gc.set_debug(gc.DEBUG_SAVEALL)
Run Code Online (Sandbox Code Playgroud)
在 python3 中,您还可以附加一个在 gc 启动和完成时运行的回调,一个简单的示例:
def f(phase, info):
if phase == "start":
print("starting garbage collection....")
else:
print("Finished garbage collection.... \n{}".format("".join(["{}: {}\n".format(*tup) for tup in info.items()])))
print("Unreachable objects: \n{}".format(
"\n".join([str(garb) for garb in gc.garbage])))
print()
gc.callbacks.append(f)
Run Code Online (Sandbox Code Playgroud)
与该函数结合gc.DEBUG_SAVEALL将显示任何无法访问的对象,这与设置DEBUG_COLLECTABLE或DEBUG_LEAK没有太大区别,只是添加回调的一个示例。