Java Memory Handling for games

Hi,
Running your game in diferent machines shows an problem about memory handling.
I tried to run my game in an poor machine that has only 2gb of ram, and I found out it starts to swap and get log performance.
I could not find yet also, the ideal GC behavior for an game, if its too lazy, it gets an big lag on the gc run, if aggressive, it seems do decrease a bit the fps.
Also, the -X parameter could fix some of this problems but since my game is made in an executable, I would need to setup it at runtime, maybe using something like HotSpotDiagnosticMXBean changing the -Xms at startup ?
I would like to know how do you guys are handling this kind of problem !
Thanks in advance,
Wag

How many times do you use ‘new’ and why so many times? :slight_smile:

If your game has different levels you can call System.gc() during loading one. This will lessen the probability that the garbage is collected while your game is running.

Maybe this page could be of some use to you: https://plumbr.eu/java-garbage-collection-handbook

My idea is currently:
Deploy the game as jar and add two batch/Sh Files which simply invoke Java with -x Parameters.

Then i will have a wiki Page on how to adjust Parameters for speed. People could do that with minecraft aswell.

Maybe I might add some native file which replaces the batch (because of steam) and Auto detects the RAM size and chooses it’s Parameters.

Note: the assetmanagers caching does also affect RAM usage, so if you load each Level as a big scene, uncaching it will half your RAM load :wink:

A lot. Its an arcade game, so enemies spaws at something like 10 objs per second, all big objects.
The game has different levels, doing the System.gc() at level start or finish helps, but for low memory computers gc is still an problem.
I was thinking to build something that sets the xms and xmx on startup, it could read how much memory free the env has and setup it dynamically, but gc is still an dilema…

no secret, reduce (or remove) every “new” during “in game” :

  • preallocate (eg: when loading level)
  • reuse (you can use a pool of instance), if at the same time you can only have 50 NPC, then it’s the size of NPC pool

to help: use a profiler (MAT, jvisualvm are free) to see where memory are created/destroy/created/destroy. Your GC should do the mininum.

Hi

Don’t try to force garbage collection, even during the pauses, it might have some very nasty side effects. Don’t use pooling, it is rarely useful and inefficient in most of the cases since Java 1.4. Don’t abuse of caching, i.e identify the life cycles of your resources, don’t keep any reference on useless things even though it leads you to load and unload some resources during the party so that the garbage collector can do its job, caching should reduce I/O operations but avoiding to store several copies of the same resource is important.

I agree with david_bernard_31 about the profilers and you can add a plugin to jvisualvm to see the direct memory footprint. Eclipse MAT is excellent to find quickly any memory leak. You should profile first, so that you have a better idea of what is wrong.

Don’t forget to manage unmanaged resources, we have already talked a lot about direct NIO buffers here.

Look at the design pattern “flyweight”. You can create many small objects and move the heavy common part of them into a separate object.

The different versions of my game use between 10 MB and 35 MB. I assume that I know what I’m talking about :wink:

I’m storing the unused ‘big’ objects (for example renderers containing shadow map textures) in collections and everything works well. I’m doing such things not only in Skullstone, which already works well, but on all codes I wrote before.
The best way is to divide your objects in two types:

  • the constant ones, created/loaded at the (level) begining, I mean when you just have enough time to let GC to stop your program for a moment,
  • the dynamic ones, which needs to be created and abandoned during the game time.

Sometimes it may look that the ‘code needs to warm up’, but it is rare and extremal situation.

But the SDK’s app deployment will already pass through the -X parameters. This whole thread is confusing me because of this.

Pass in the proper -Xmx and also a setting for direct memory (make that one at least double what -Xmx is). The SDK exe generation will pass these in if you’ve configured them. At least it always has.

Made in an executable how?

Ok, there is two diferent problems here, one gc and other jvm parameters…
I am using an special windows exe generator from the jar I get from the compiler.
I can configure some fixed parameter in the jar / exe , but I need to have an option to change the jvm options at runtime, or at startup, I am looking on that.
About the gc, I am suspecting my problem with gc is not related to the 3d spatial objects directly, but with the physical objects… I made some debug and found out that after I create and release objects in the jbullet it seens to have some kind of memory leak, and the tick speed gets lower and lower by time, there is nothing in the debug on screen thought…
Do you know if in the jm3.1 it uses native bullet ?

I changed the static bulletappstate from main class into inside the game play appstates, this way I am removing/re-creating all the bulletappstate every time I atach/detach the game play, it fixed the problem with gc …
What it means is that there is some kind of bug in the jbullet that is not cleaning all references of objects internally, my best guess is the joints objects ( I create thousends of this objects in my game ).

If you are requiring JRE 8 to run your game, you can use the new GC:
-XX:+UseG1GC

It should be less intrusive. Not eliminating the lag completely of course…