OutOfMemoryException

Hello,
in my new game it seems that after playing for a while a user gets an OutOfMemoryError. He couldn’t even start it at the beginning before I sat the initial heap size to 1024MB and I also sat the max heap size to 2048MB. But after playing for a while it seems that that limit is also reached. Should I simply set the value even higher or am I doing something wrong? I didn’t really look into the memory things while writing the game because as I was playing it, I never experienced any issue (even if I tested it running a long time).
The machine of my friend has 12GB of RAM so that shoudln’t be any problem. And I could also start the game without setting the heap size while he would get a Memory error…
He doesn’t get the exception very often though so maybe it really is enough to set the maximum memory to more than 2048MB?

Sounds rather like a memory leak to me. Check for object references that are never released. I also have read somewhere that cyclic references can cause memory leaks in Java, although I couldn’t verify this, but just to be sure, you could also consider using weak references whenever it’s reasonable.

Maybe fire up jvisualvm and have a look at the memory while running the app. See what objects are taking up the memory and how much.

Okay so it surely is about ibject references? The last playthrough went very well so it somehow is a bit random… But I could definetely clean up some code and references. Thank you guys!

What kind of oom? If you run out of direct memory then increasing the heap size might make the issue worse. Java cannot track how much direct memory is actually used so its lazily cleaned when theres a GC. When you make the heap bigger theres less GCs happening and the direct memory will be cleaned up even less often.

It said Direct buffer memory. But the game also threw the exact same exception when he started it and when I hadn’t set the initial heap size to 1024MB.

Well then increase the direct memory and not the heap.

Oh well I’m stupid lol I didn’t know about this option as I just read about the heap :confused: Well now it’s working fine.

Thanks!

Glad it worked out for you. Looks like you were just about hovering on the threshold where there was enough cleanups to keep enough direct memory free most of the time.

Btw contrary to normal java guidlines System.gc() is your friend in game development.

If you have something like level load, game end or other non interactive loading parts, manually calling it will not be really noticeable but often clean up quite much stuff, and hopefully prevent a full gc running while playing the level.

1 Like

Yeah I sometimes had the problem that my FPS dropped to 5 fps for a couple of seconds I assume that was because of garbage collection… Thanks for the hint!

Also, it’s quite likely that when this happens you have your heap set too big. It’s counter-intuitive but when your heap is too big, the GC will not run its incremental clean-up as often. Meanwhile, you are allocating all kinds of direct memory that is growing and growing until you run out and force a hard-GC.

In general, keep a huge direct memory size and a moderate heap size and your game will be happier.

Also, where possible, avoid needless per-frame garbage.

So what would you recommend? XX:MaxDirectMemorySize=2048M; Xms512m; Xmx1024m and System.gc() on every loading screen? Is that reasonable?

Unless you have reason to do otherwise, I’d halve both of those values.

The thing about huge numbers is that by the time the game finally needs to do a full GC the heap is HUGE and it will take that much longer.

Halve the values and add some debug information to your HUD showing used versus max memory. Just keep an eye on that. You can copy the relevant bits from this app state to do it:
https://code.google.com/p/simsilica-tools/source/browse/trunk/IsoSurfaceDemo/src/main/java/com/simsilica/iso/demo/DebugHudState.java

Ok it works fine with the half too. Thanks!