I have a python application that has some performance hiccups. I want to add the garbage collector's events (especially, when does it get called) to my logs. Is it possible?
thanks.
I have a python application that has some performance hiccups. I want to add the garbage collector's events (especially, when does it get called) to my logs. Is it possible?
thanks.
http://docs.python.org/library/gc.html#gc.set_debug
You can set the Flags, but they get written to stderr.
Available flags are
gc.DEBUG_STATS
gc.DEBUG_COLLECTABLE
gc.DEBUG_UNCOLLECTABLE
gc.DEBUG_INSTANCES
gc.DEBUG_OBJECTS
gc.DEBUG_SAVEALL
gc.DEBUG_LEAK
ALSO
When you are dealing with performance, you might wish to profile your code for exhaustive Loops or Function calls. You can use cProfile
or hotshot
. More here http://docs.python.org/library/profile.html
Python (at least CPython version 2.x) uses reference counting to implement its garbage collector (cf. Why Java and Python garbage collection methods are different?), so it's not really "called", as it is in Java.
Refcounting
means that each time a new reference to a given object is created, a counter is incremented, each time the reference is lost (end of scope, reassignment, ...), the counter is decremented. When it reaches 0, the object memory is freed.
So the solution Python offers to your problem is to override the __del__
method of the object:
class test:
def __del__(self):
#self is about to be freed, do what ever you want
pass
EDIT: According to the link above, there is another mechanism running periodically:
CPython (reference counting is not part of python itself, but part of the C implementation thereof) catches circular references with a separate garbage collection routine that it runs periodically...
but only involved in case of circular references.
EDIT 2:
As mentioned in the comments and here, __del__
is not the safest solution. Here is a certainly better way to achieve a similar behavior:
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