Python: 记录垃圾回收器的日志

3

我有一个Python应用程序,性能存在一些问题。我希望将垃圾收集器的事件(尤其是何时调用)添加到我的日志中。这是否可能?

谢谢。

2个回答

6

谢谢你的性能提示,但我的应用程序在零散的地方出现了这些问题,通常不涉及循环或递归。这就是我怀疑垃圾回收器的原因。 - r0u1i

1

Python(至少CPython版本2.x)使用引用计数来实现其垃圾回收器(参见为什么Java和Python的垃圾回收方法不同?),因此它并不像Java那样真正“被调用”。

引用计数意味着每次创建给定对象的新引用时,计数器会递增,每次引用丢失(作用域结束,重新分配等),计数器会递减。当计数器达到0时,对象内存将被释放。

因此,Python提供给您的问题的解决方案是覆盖对象的__del__方法:

class test:
    def __del__(self):
         #self is about to be freed, do what ever you want 
         pass

编辑: 根据上面的链接,还有另一种机制定期运行:

CPython(引用计数不是Python本身的一部分,而是C实现的一部分)通过单独运行的垃圾回收程序捕获循环引用...

但仅在循环引用的情况下才涉及。

编辑2: 如评论和此处所述,__del__并不是最安全的解决方案。以下是一种更好的实现类似行为的方法:

import weakref

class test:
    pass

t = test()

def prepare_cb(obj):
  #save information about the obj
  uid = id(obj)

  def do_some_logging(weak):
     print "Object %s cleaned up" % uid

  return do_some_logging

weak = weakref.ref(t, prepare_cb(t))

del t

这仅适用于自定义类,而不适用于内置类。此外,源代码中的“ALL”类都必须进行编辑。 - meson10
1
GC模块只处理循环引用。定义__del__实际上是一个可怕的想法,因为它使对象无法被循环GC收集。 - John La Rooy
@gnibbler: 说得好,文档已经很清楚了。因此,它取决于代码中循环引用的频率以及您实际想要了解的垃圾收集信息。 - Kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接