我有一个Python应用程序,性能存在一些问题。我希望将垃圾收集器的事件(尤其是何时调用)添加到我的日志中。这是否可能?
谢谢。
我有一个Python应用程序,性能存在一些问题。我希望将垃圾收集器的事件(尤其是何时调用)添加到我的日志中。这是否可能?
谢谢。
http://docs.python.org/library/gc.html#gc.set_debug
您可以设置标志,但它们会被写入 stderr。
可用的标志包括:
gc.DEBUG_STATS
gc.DEBUG_COLLECTABLE
gc.DEBUG_UNCOLLECTABLE
gc.DEBUG_INSTANCES
gc.DEBUG_OBJECTS
gc.DEBUG_SAVEALL
gc.DEBUG_LEAK
另外
当你处理性能问题时,你可能希望对循环或函数调用进行全面的分析。你可以使用cProfile
或hotshot
。更多信息请参见http://docs.python.org/library/profile.html
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
__del__
实际上是一个可怕的想法,因为它使对象无法被循环GC收集。 - John La Rooy