Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualsmr

Posted 16 January 2013 - 05:09 PM

Edit: I realized everything I said before was based on the assumption spellSprites is a list. It's not. It's a pygame sprite group. Sorry!

 

In any case, check to make sure you're not tucking away any references to these sprite instances anywhere else in your code. If you are, then this could be the source of your leak. As a diagnostic, call gc.collect() after your clean-up method. If the sprites are gone out of memory after a collection, then you could have created a circular reference somewhere between the sprite and some other object. Python uses reference counting to know when to clean up an object, but it also has a garbage collector that runs periodically that can recognize and collect objects lingering only due to circular references.


#2smr

Posted 16 January 2013 - 04:21 PM

.kill() is not sufficient to remove it from memory in your case because you're keeping it in spellSprites. In your else clause, you also need to remove it from spellSprites. Keep in mind that you're iterating over this list at that point, so you can't directly remove it from the list until execution is outside the loop. An easy (and inefficient) way to do clean up would be to do this after your loop:

 

self.spellSprites = [spell for spell in self.spellSprites if spell.alive]

 

This is creating a new list every frame. It also assumes there's a property on your sprite indicating its living/dead status. If there isn't one, you can just set it yourself after calling .kill(). This also assumes that you haven't created any references to this object's spellSprites instance somewhere else. If that's the case, then you'd end up with some very strange results. Hint: It's probably a design flaw if you're keeping references to spellSprites anywhere else besides in the object itself anyway. I'd refactor to no longer keep references to members outside of the object instance that owns those members.

 

I do see that under a circumstance that you are emptying that list. If you're still holding references to sprites and you know they've been removed from spellSprites and theSpell has fallen out of scope, you may have created a circular reference somewhere. Python uses reference counting to keep track of when to remove items from memory. As a test, perform a garbage collection (gc.collect()) after your loop and see if that sprite is still in memory. If running the garbage collection makes the difference then you probably have created a circular reference to the sprite somewhere. Python's garbage collector is smart enough to find and collect circular references, but it only runs periodically.


#1smr

Posted 16 January 2013 - 04:14 PM

.kill() is not sufficient to remove it from memory in your case because you're keeping it in spellSprites. In your else clause, you also need to remove it from spellSprites. Keep in mind that you're iterating over this list at that point, so you can't directly remove it from the list until execution is outside the loop. An easy (and inefficient) way to do clean up would be to do this after your loop:

 

self.spellSprites = [spell for spell in self.spellSprites if spell.alive]

 

This is creating a new list every frame. It also assumes there's a property on your sprite indicating its living/dead status. If there isn't one, you can just set it yourself after calling .kill().

 

I do see that under a circumstance that you are emptying that list. If you're still holding references to sprites and you know they've been removed from spellSprites and theSpell has fallen out of scope, you may have created a circular reference somewhere. Python uses reference counting to keep track of when to remove items from memory. As a test, perform a garbage collection (gc.collect()) after your loop and see if that sprite is still in memory. If running the garbage collection makes the difference then you probably have created a circular reference to the sprite somewhere. Python's garbage collector is smart enough to find and collect circular references, but it only runs periodically.


PARTNERS