Python:记录垃圾收集器

时间:2011-11-18 07:53:55

标签: python garbage-collection

我有一个python应用程序,有一些性能打嗝。我想将垃圾收集器的事件(特别是何时被调用)添加到我的日志中。可能吗?

感谢。

2 个答案:

答案 0 :(得分:5)

http://docs.python.org/library/gc.html#gc.set_debug

你可以设置Flags,但是它们会被写入stderr。

可用标志

gc.DEBUG_STATS
gc.DEBUG_COLLECTABLE
gc.DEBUG_UNCOLLECTABLE
gc.DEBUG_INSTANCES
gc.DEBUG_OBJECTS
gc.DEBUG_SAVEALL
gc.DEBUG_LEAK

同时

在处理性能时,您可能希望对代码进行详尽的循环或函数调用。您可以使用cProfilehotshot。更多http://docs.python.org/library/profile.html

答案 1 :(得分:1)

Python(至少CPython版本2.x)使用​​引用计数来实现其垃圾收集器(参见Why Java and Python garbage collection methods are different?),因此它不像Java中那样被“调用”。

Refcounting表示每次创建对给定对象的新引用时,计数器都会递增,每次引用丢失时(范围结束,重新分配......),计数器都会递减。当它达到0时,释放对象内存。

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

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

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

  

CPython(引用计数不是python本身的一部分,但是它的C实现的一部分)捕获带有单独的垃圾收集例程的循环引用,它定期运行...

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

编辑2: 正如评论和here中所述,__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