🔒 Locked
[java] Garbage Collection Issue
Advertisement
Original Post
I've been working on a game project for the last couple months now and have run into a little issue. My game tends to hiccup (pause from 1 - 2 seconds) whenever the Java Virtual Machine decides to garbage collect. The reason there is a substantial pause is because the game employs a lot of brief in-game objects (lasers, bullets, effects, etc). Is there anyway to control garbage collection times? Is there anyway around this problem? Any help is appreciated.
Thanks for the input, and yeah I've already begun re-writing my classes to do just that.. I just was hoping at first that there was an easy way out :P
Be careful with recycling objects in Java!
Java has a generational garbage collector and there's a different cost associated with collecting each generation. Short-lived objects are very cheap to collect and long-lived objects are collected so infrequently, that they don't add much of an overhead. It's objects that live long enough to survive the first generation but not long enough to be added to the pool of "old objects" that are the most expensive to collect.
So if you choose to recycle objects, make sure you hold on to them for as long as your game/level is running. Otherwise the garbage collector will perform expensive "full collections" more frequently and your hickup problem will only become worse.
Also note that the Java GC keeps track of past collections and will adjust its collection behavior accordingly. If it performs a full collection but doesn't actually reclaim any memory, it may choose to perform collections less frequently in the future. So make sure that while your game is running, the garbage collector only reclaims short-lived objects as they are treated differently.
In general though, the hickup problem is something you'll ultimately have to live with (to some degree). The only generational collector I know that does not have this problem is the one used in Erlang, and that's because garbage collection in Erlang is a lot easier than it is in Java. That is also precisely the reason why the Adobe Flash VM relies primarily on reference-counting.
Java has a generational garbage collector and there's a different cost associated with collecting each generation. Short-lived objects are very cheap to collect and long-lived objects are collected so infrequently, that they don't add much of an overhead. It's objects that live long enough to survive the first generation but not long enough to be added to the pool of "old objects" that are the most expensive to collect.
So if you choose to recycle objects, make sure you hold on to them for as long as your game/level is running. Otherwise the garbage collector will perform expensive "full collections" more frequently and your hickup problem will only become worse.
Also note that the Java GC keeps track of past collections and will adjust its collection behavior accordingly. If it performs a full collection but doesn't actually reclaim any memory, it may choose to perform collections less frequently in the future. So make sure that while your game is running, the garbage collector only reclaims short-lived objects as they are treated differently.
In general though, the hickup problem is something you'll ultimately have to live with (to some degree). The only generational collector I know that does not have this problem is the one used in Erlang, and that's because garbage collection in Erlang is a lot easier than it is in Java. That is also precisely the reason why the Adobe Flash VM relies primarily on reference-counting.
Tuning the GC in Java is something of a black art. Sun has lots of documentation about it here.
JProfiler 5 has some nifty tools for monitoring each section of memory used.
For a complete stab in the dark, try passing these options to your application:
-XX:+UseParallelGC
or
-XX:+UseConcMarkSweepGC
Also, passing -verbose:gc helps diagnose problems.
Regards
elFarto
JProfiler 5 has some nifty tools for monitoring each section of memory used.
For a complete stab in the dark, try passing these options to your application:
-XX:+UseParallelGC
or
-XX:+UseConcMarkSweepGC
Also, passing -verbose:gc helps diagnose problems.
Regards
elFarto
Thanks for the information and suggestions guys. Its nice to know that there are people out there who are willing to help :)
In general I find temporary objects which live over multiple frames (bullets, effects, etc.) don't have much of an affect on the garbage collector. It's temporary stuff like 2d vectors or points used for gameplay/collision which can potentially be created hundreds or thousands of times per frame which are the ones to watch out for.
Try VisualVM and grab the "Visual GC" plugin and you'll be able to see exactly what's going on under the hood in the garbage collector.
Edit: And where possible use the latest VM. 1.5 and 1.6 both have substantially faster garbage collection that previous versions.
Try VisualVM and grab the "Visual GC" plugin and you'll be able to see exactly what's going on under the hood in the garbage collector.
Edit: And where possible use the latest VM. 1.5 and 1.6 both have substantially faster garbage collection that previous versions.
Thanks for the info. Ill go check it out :)
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement