I am writing a simple platform game, and I’ve found that when removing ‘ghost’ instances, they persist and are not garbage collected. It seems that although I am removing all references, the ghost objects have some kind of internal references that are preventing them being garbage collected. Specifically they have attributes which are method switches.
The following code illustrates my problem:
import weakref
weak_ghosts = weakref.WeakKeyDictionary()
class Ghost(object):
def __init__(self):
#pass
self.switch = {'eat':self.eat, 'sleep':self.sleep}
def eat(self):
pass
def sleep(self):
pass
ghost = Ghost()
weak_ghosts[ghost] = None
#ghost.switch = {} # uncomment this line and ghost is successfully removed
del ghost
print "number of ghosts =", len(weak_ghosts)
#output:
number of ghosts = 1
Questions:
- What is actually going on?
- What should I be doing to avoid this situation?
- Am I using the correct methodology for making a switchable dictionary of methods?
There is a circular reference created by
self.switchreferencing the object it’s part of. Check this out:Prints:
So the actual object was just cleaned on shutdown.
You can run the GC manually to see the effect. Add this to the end of the script above:
Now you’ll see:
Note that by default, this GC is enabled and will run from time to time. It will clean up your
ghostobjects because they become unreachable circular references.