BUG: Objects not being Destroyed/Freed properly
by Scott Cameron · in Torque X 2D · 11/18/2009 (10:17 pm) · 9 replies
I've found that if I have a TileLayer with X number of Tiles if I UnLoad the scene it does not delete/free all the TileObjects that were created with the TileLayer.
I've also verified that there are other Objects left in memory as well.
how I found this out was to add a static int to TorqueObject
and I also added a constructor and finalizer
I'm not 100% sure that this is catching every object but I do know there are memory leaks here somewhere.
for instance I have a game that has a mainmenu that loads a scene and then I can leave the scene and return back to the main menu using the Sceneloader.Load/UnLoad methods.
Before my scene is loaded on my main menu I have 17 TorqueObjects created when my scene gets loaded I have 340+ TorqueObjects Created When I leave my level and unload the scene file so I'm back at my mainmenu I have 300+ objects still.
I've also verified that there are other Objects left in memory as well.
how I found this out was to add a static int to TorqueObject
and I also added a constructor and finalizer
static int objCount = 0;
public TorqueObject()
{
objCount++;
}
~TorqueObject()
{
objCount--;
}
public static int GetObjCount()
{
return objCount;
}I'm not 100% sure that this is catching every object but I do know there are memory leaks here somewhere.
for instance I have a game that has a mainmenu that loads a scene and then I can leave the scene and return back to the main menu using the Sceneloader.Load/UnLoad methods.
Before my scene is loaded on my main menu I have 17 TorqueObjects created when my scene gets loaded I have 340+ TorqueObjects Created When I leave my level and unload the scene file so I'm back at my mainmenu I have 300+ objects still.
#2
It's worth pointing out that applying the fix in the thread mentioned above doesn't change anything - I get the exact same numbers as without it.
11/19/2009 (3:41 pm)
I've spent some time having a look into this today and the scene objects are being unloaded as they should be. There *are* unfinalized TorqueBase and TorqueObject instances (TorqueObject extends TorqueBase). I'm not sure why they aren't being finalized - but it's possible the garbage collector simply hasn't decided to collect them yet (I'll look into it some more if I get more time, but it's not causing me any issues at the moment).It's worth pointing out that applying the fix in the thread mentioned above doesn't change anything - I get the exact same numbers as without it.
#3
A quick simple fix for tilemaps would be to add the following method to the T2DTileLayer class
this will clean up the TileObjects that are still hanging around but there are other objects that stick around like SceneGraphs, AnimationData etc.
11/19/2009 (7:25 pm)
I thought it was a Garbage collection issue also but I bound a System.GC.Collect() call to an input and didn't get any change in numbers till I implemented a fix for the tile maps then i could actully see the objects getting destroyed/collected.A quick simple fix for tilemaps would be to add the following method to the T2DTileLayer class
public override void OnUnregister()
{
base.OnUnregister();
//BUGFIX: SRC - temporary fix to free memory used by Tiles when a TileMap gets Unregistered
_tilesArray = null;
}this will clean up the TileObjects that are still hanging around but there are other objects that stick around like SceneGraphs, AnimationData etc.
#4
stackoverflow.com/questions/1587245/c-in-what-cases-should-you-null-out-referenc...
msdn.microsoft.com/en-us/library/aa691138(VS.71).aspx
Basically the garbage collector checks to see if stuff is reachable - if not then it can be collected. If you really are having to null the tilesArray to get it to collect those objects then that means there is still a reference to the tilemap somewhere, which isn't good at all when it was supposed to have been completely unloaded.
As noted earlier, when I manually removed everything from the scenegraph it didn't change the slow build up of unfinalized objects. Further investigation needed I think.
11/19/2009 (8:38 pm)
You shouldn't need to be nulling out the tilesArray if the tilemap is itself no longer referenced from anywhere. Nulling might speed up garbage collection on the array and the objects it references, but eventually everything should get collected anyway.stackoverflow.com/questions/1587245/c-in-what-cases-should-you-null-out-referenc...
msdn.microsoft.com/en-us/library/aa691138(VS.71).aspx
Basically the garbage collector checks to see if stuff is reachable - if not then it can be collected. If you really are having to null the tilesArray to get it to collect those objects then that means there is still a reference to the tilemap somewhere, which isn't good at all when it was supposed to have been completely unloaded.
As noted earlier, when I manually removed everything from the scenegraph it didn't change the slow build up of unfinalized objects. Further investigation needed I think.
#5
Also the code I posed to null the _tilesArray was just a quick way for me to free those objects without that code I've let my game app sit for quite awhile and no memory got freed by itself or when I specificly called told the garbage collector to do a collection and I'm not that familar with the engine to see what objects are still referencing these objects.
I wish there was a way for Torque X to dump all its Allocated Objects and whats Referencing them would make this alot easier to find and fix.
11/19/2009 (8:51 pm)
I agree and thats the bug there are still objects that are being referenced somewhere in the system.Also the code I posed to null the _tilesArray was just a quick way for me to free those objects without that code I've let my game app sit for quite awhile and no memory got freed by itself or when I specificly called told the garbage collector to do a collection and I'm not that familar with the engine to see what objects are still referencing these objects.
I wish there was a way for Torque X to dump all its Allocated Objects and whats Referencing them would make this alot easier to find and fix.
#6
11/20/2009 (10:53 am)
I'll maybe get time to look into it some more over the weekend.
#7
Long story short, my code was leaking textures - stupid mistake and now fixed. Many small undisposed textures adds up to enough to tip the game over the memory limit.
As regards TX, it is still leaking, but in comparison to the leak I just plugged the player would have to play 100s of games without quitting to the dashboard, in order to tip the game over the memory limited. I'd imagine that for many games the TX leak will not be a major issue - you'd have to be *really* close on the memory limit, which would be playing with fire anyway unless _everything_ you allocate is managed in pools.
In conclusion then, I'm not going to worry about the TX leak for now as it doesn't seem to pose a serious problem (at least for any of my current projects), although I will probably look at it in my spare time anyway, to satisfy my curiosity.
(incidentally, I used dotTrace to find my memory leak - there is a no holes barred 14 day free trial available if you want to try it out - it can tell you all about what is allocated in memory, what is finalized, etc - as well as doing CPU profiling)
11/21/2009 (11:35 pm)
One of my projects is getting close to the xbox memory limit and was crashing after a few playthroughs so the leaking objects issue went up on my priority list all of a sudden :-)Long story short, my code was leaking textures - stupid mistake and now fixed. Many small undisposed textures adds up to enough to tip the game over the memory limit.
As regards TX, it is still leaking, but in comparison to the leak I just plugged the player would have to play 100s of games without quitting to the dashboard, in order to tip the game over the memory limited. I'd imagine that for many games the TX leak will not be a major issue - you'd have to be *really* close on the memory limit, which would be playing with fire anyway unless _everything_ you allocate is managed in pools.
In conclusion then, I'm not going to worry about the TX leak for now as it doesn't seem to pose a serious problem (at least for any of my current projects), although I will probably look at it in my spare time anyway, to satisfy my curiosity.
(incidentally, I used dotTrace to find my memory leak - there is a no holes barred 14 day free trial available if you want to try it out - it can tell you all about what is allocated in memory, what is finalized, etc - as well as doing CPU profiling)
#8
I've used dottrace and I found that TX is leaking IndexBuffers and VertexBuffers along with Textures and Effects and a few other things I can't remember right now. but the tile objects were the worst for me so far.
I'm a little concerened about the Texture leaks cause I'm probably going to be adding lots more texures to my levels and don't want the game to crash with OOM errors but we'll have to see what happens.
11/22/2009 (2:12 pm)
Was the leak you plugged up from your own code? or was it something in TX source that you can share?I've used dottrace and I found that TX is leaking IndexBuffers and VertexBuffers along with Textures and Effects and a few other things I can't remember right now. but the tile objects were the worst for me so far.
I'm a little concerened about the Texture leaks cause I'm probably going to be adding lots more texures to my levels and don't want the game to crash with OOM errors but we'll have to see what happens.
#9
VertexBuffers and IndexBuffers - you might want to check whether that is a leak or whether TX is just pooling them for reuse.
I've not seen TX leaking textures - that was my own fault. Rest assured the project I was referring to earlier is touching the memory limit (and then some) and anything more than a trivial memory leak shows up relatively quickly as an oom error.
(I've recently applied dxt compression to static sprites though, so that will give us a bit more headroom - we also use content loading/unloading)
11/22/2009 (2:48 pm)
My leak was my own fault :(VertexBuffers and IndexBuffers - you might want to check whether that is a leak or whether TX is just pooling them for reuse.
I've not seen TX leaking textures - that was my own fault. Rest assured the project I was referring to earlier is touching the memory limit (and then some) and anything more than a trivial memory leak shows up relatively quickly as an oom error.
(I've recently applied dxt compression to static sprites though, so that will give us a bit more headroom - we also use content loading/unloading)
Torque Owner Matthew Hoesterey
http://www.garagegames.com/community/forums/viewthread/76056
It would be great if the unload issue was fixed though. :)