Leaks in MiniB3D?

BlitzMax Forums/MiniB3D Module/Leaks in MiniB3D?

jtfrench(Posted 2012) [#1]
Hi,

I'm trying to track down some memory leaks in my multithreaded MiniB3D game on Windows. I was suspecting textures might be an issue, so I wrote a simple test program to observe memory usage. I repeatedly load a 4096 by 4096 (that's the max for my graphics card) texture:
Import Sidesign.MiniB3D

Graphics3D 800,600,1,2

Local testTexture:TTexture;

For Local i:Int = 0 Until 9999

testTexture = LoadTexture("name_of_texture.JPG");
Print "Test"
If (testTexture)
testTexture.FreeTexture();
EndIf

Next

'Give garbage collector a chance to collect if necessary
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;
Delay 1000;


I ran this in multithreaded mode through gDEBugger, here's what I see. The memory usage rises as it loads a few textures, then the garbage collector is triggered and it drops back down. The problem is, each time it drops down, it doesn't drop down quite as far, and each time it goes up, it peaks a little bit higher. Eventually, the program crashes when the process's virtual memory hits about 1.7 GB and the working set hits about 1.5 GB.

Why am I seeing this leak?

If I comment out the "Graphics3D 800,600,1,2", the memory usage still oscillates, but eventually settles into a pattern and never goes past a certain peak.

If I leave the Graphics3D in, but replace the load/free code with a delay, I don't see any leaks, so its not like Graphics3D is causing a leak just because it was created.

Any ideas of what's going on here?

Thanks,
Jason


ima747(Posted 2012) [#2]
This is the gremlin in the multithreaded GC I've been chasing for a loooong time now. I find things are better with manual collection and careful management of objects (nulling things when done with them etc.) but there's a monster in there somewhere that still eludes me.


jtfrench(Posted 2012) [#3]
Indeed...I feel this has been the root of all my trickier BlitzMax development problems...

Does anyone (perhaps from Mark et. al.) have a definitive answer on multhithreaded GCs leaking behavior and how to work around it?


Captain Wicker (crazy hillbilly)(Posted 2012) [#4]
I dont know if this has memory leaks or not but ive tried it and its very good!
http://code.google.com/p/warner-engine/

Note: it is relatively slow compared to minib3d but is worth trying. :)


jtfrench(Posted 2012) [#5]
Hey Captain Wicker,

Thanks for the recommendation, but unfortunately I'm a bit too far into development to switch engines now. Hopefully I can get an answer on how to remedy the issue while sticking with minib3d...


Krischan(Posted 2012) [#6]
I noticed two memory leaks in minib3d, too. One small in the RAM and one large in the GPU RAM. I got the GPU leak fixed here simply switching over to the current 0.54 package (looks like I used a strange patched 0.53 to something version before).

The RAM leak, well, changed its behaviour somehow. I use Orbmu2k's Top 5 Gadget in Windows 7 to notice the changes. Something is eating up the RAM constantly, perhaps 1MB per second (minib3d is only rendering the finished planet in my planet creator) and sometimes the RAM frees some 100/200MB without any action from my side. If I compile the source without threading the leak is gone. Very strange. Oh, and I don't use threads, yet. Only a type.

Last edited 2012


jtfrench(Posted 2012) [#7]
That patch in 0.54 definitely did fix a significant GPU leak. I'm still seeing the memory climb on the CPU side (though not as much). I'm going to do a few more tests in-game and see how it holds up to higher amount of RAM being alloced/delloced.


jtfrench(Posted 2012) [#8]
So I put some printouts in bbMemAlloc/bbMemFree as well as heapAlloc/heapFree, and ran my game, here's what I am seeing after a short run:

- About 25,000 more calls to heapAlloc than heapFree
- About 3,000 more calls to bbMemAlloc than heapFree
- About 1.2 GB of memory leaks from memory that isn't heapFree'd
- About 200 MB of memory leaks from memory that isn't bbMemFree'd
- The largest chunk leaked from heap methods is about 80 KB
- The largest chunk leaked from bbMem methods is 16 MB

I'm going to run another test to try to track down the culprits of the largest leak, but does any of this data help clear things up? What seems alarming, what seems irrelevant?


ima747(Posted 2012) [#9]
This is in line with what I was seeing when working on this. Stuff is made but for some reason isn't cleared. It only happened in the multithreaded GC and I could never narrow down exactly what it was. The problem is that *most* stuff is handled, but not everything... and I haven't a clue why some things slip through the cracks. It would be one thing if it happened in the single threaded collector as well, but that seems fine, which leads me to believe it's a problem with the collector and not specific modules (this is just a theory but, flip a switch and problems start, the switch might have something to do with it...)

The nearest I could figure was that some things that try to get freed are locked, so the free can't happen, but they are discarded anyway so then there's no reference, hence the leak. My solution was to disable the garbage collector and manually tell it to collect when I knew threads weren't doing anything. I don't think it solved the issue entirely, and certainly did nothing to get to the root of the problem, but it has been working for me. I suspect the leaking things are thread specific, not MiniB3D things, but again, that's just a theory.

I think there's either a problem with the multithreaded collector, that it thinks it's cleaned things up when it actually hasn't, drops the reference and therefore leaks them, OR theres a leak in the threading system itself, as, again, things don't leak without threading enabled.