Jump to content
  • Advertisement
Sign in to follow this  
Black Knight

Python Event class and memory leak

This topic is 3013 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys,I am pretty new to python and I have a problem that is bugging me.The following code is a small application that replicates the issue which happens in a larger program.Here is the code :

import gc

class Event:
	def __init__(self, name):
		self.targets = set()
		self.__name__ = name
	def __repr__(self):
		return 'event ' + self.__name__
	def __call__(self, *a, **kw):
		for f in self.targets: 
			f(*a, **kw)
	def __iadd__(self, f):
		return self
	def __isub__(self, f):
		while f in self.targets: self.targets.remove(f)
		return self

class GUIObject():
	def __init__(self):
		self.OnClicked = Event('OnClicked')

class Map():
	def __init__(self):
		self.button = GUIObject()
		self.button.OnClicked += self.onButtonClicked
	def onButtonClicked(self):

class Game():
	def __init__(self):
		self.map = Map()
		self.map = Map()


game = Game()

print gc.collect()

print gc.garbage

When I run this program I get the following output.
gc: collectable <dict 022BAC00>
gc: collectable <Map instance at 022C0E90>
gc: collectable <dict 022C1150>
gc: collectable <GUIObject instance at 022C0EB8>
gc: collectable <dict 022C11E0>
gc: collectable <Event instance at 022C0EE0>
gc: collectable <set 01E74D50>
gc: collectable <instancemethod 022B7800>
[{'button': <__main__.GUIObject instance at 0x022C0EB8>}, <__main__.Map instance
 at 0x022C0E90>, {'OnClicked': event OnClicked}, <__main__.GUIObject instance at
 0x022C0EB8>, {'__name__': 'OnClicked', 'targets': set([<bound method Map.onButt
onClicked of <__main__.Map instance at 0x022C0E90>>])}, event OnClicked, set([<b
ound method Map.onButtonClicked of <__main__.Map instance at 0x022C0E90>>]), <bo
und method Map.onButtonClicked of <__main__.Map instance at 0x022C0E90>>]

So does this mean I have a memory leak in this code since the gc.garbage list has all those elements.If there is a memory leak is it caused by a circular reference?

Share this post

Link to post
Share on other sites
From the python docs:
With no arguments, run a full collection.

So yeah, when you're printing all the information and you just garbage collected everything, you'll get a full list.

When I ran it without the gc.collect(), I get this:

gc: collectable <dict 0149BED0>
gc: collectable <Map instance at 014A2080>
gc: collectable <dict 0149BB70>
gc: collectable <GUIObject instance at 014A20A8>
gc: collectable <dict 0149BD20>
gc: collectable <Event instance at 014A20D0>
gc: collectable <set 012E8D50>
gc: collectable <instancemethod 014963C8>

Which is what you would expect since there's no reason to be garbage at the time of the print, and then everything is collected as the program ends.

Furthermore, there aren't any cyclic references that I can see, which is usually why something would be uncollectable. However, if there is something I'm missing, pay attention to this info from the python docs under gc.garbage...


Objects that have __del__() methods and are part of a reference cycle cause the entire reference cycle to be uncollectable, including objects not necessarily in the cycle but reachable only from it. Python doesn’t collect such cycles automatically because, in general, it isn’t possible for Python to guess a safe order in which to run the __del__() methods. If you know a safe order, you can force the issue by examining the garbage list, and explicitly breaking cycles due to your objects within the list. Note that these objects are kept alive even so by virtue of being in the garbage list, so they should be removed from garbage too. For example, after breaking cycles, do del gc.garbage[:] to empty the list. It’s generally better to avoid the issue by not creating cycles containing objects with __del__() methods, and garbage can be examined in that case to verify that no such cycles are being created.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!