我的理解是,在以下情况下,Python中的内存泄漏(至少是> Cpython 2.0)只能 :
__del__
方法当然,我们需要区分 实际内存泄漏 (一个程序,其中对象永远不能通过垃圾收集器回收或定期引用计数)一个程序,它只是耗尽了内存,因为它不断分配永不消亡的对象 - (但仍然触手可及) - 通常是因为它们的参考图连接了一些全局变量。
为了区分这两种情况(即实际的内存泄漏与只保持分配永不过时的可收集对象的程序),我们可以简单地连续调用gc.collect()
并检查返回值是否为0
?
换句话说,如果以下程序永远不会失败AssertionError
(由于线程2中的断言)我们有效证明有 否内存泄漏 (如上所述)?
Thread 1:
... run actual application code ...
Thread 2:
while True:
num = gc.collect()
assert num == 0
time.sleep(WAIT_TIME)
要清楚,我只是问这个程序是否会证明上面的案例(1)和(2)所定义的实际内存泄漏没有发生 - 我意识到这不会证明该程序将会由于分配太多,永远不会耗尽内存。
答案 0 :(得分:0)
即使没有内存泄漏,此程序也很可能抛出AssertionError
。它会在GC收集任何内容时执行此操作(gc.collect()
在此情况下返回非零值)。 OTOH,gc.collect()
不会收集您所指的"实际的内存泄漏,"所以他们 不会在gc.collect()
返回值中报告。
简而言之,不,这个程序根本不会正确检测内存泄漏。如果你想要抓住案例(1),你可以定期检查以确保gc.garbage
为空,但这不会遇到案例(2),因为GC只涉及管理扩展模块' s内存,如果模块询问(即使这样,只在模块正确跟踪其拥有的引用的范围内)。对于一般情况,您需要类似Valgrind的内容。