[java] controlling garbage collection

Started by
8 comments, last by princec 18 years, 10 months ago
hi, im fairly new to game programming so i never considered the garbage colloctor a problem before. but is there a way (or is it worth it) to optimize garbage collection in java, perhaps incorporate it into the main loop and call it after rendering or something?
//My SignatureString sig = "Rangler";System.out.println(sig);
Advertisement
In short, no.
Just don't worry about it. 99% of the time its not an issue. If it -becomes- an issue theres a couple of different strategys you can use to minimize the problems. Don't create thousands of tiny objects on the heap for example, use pools of pre-created objects in situations like that.


D.
You can use GC analysis tools to help optimize your application for GC if it becomes problematic. Also, Sun's JVM has more than one GC implementation you can use (via a command line switch), so you can test each to determine which affects the app less. Keep your code 'GC friendly', 'think' in Java and not another language so that you don't do silly things (Josh Bloch's book 'Effective Java' is a great help there) and you'll be fine.
It might help more if you mentioned what your motivation for doing so is--is your project using too much memory?
I'll just chime in and add another +1 to what the others say: you almost certainly will never have a problem with GC actually doing anything, unless you start doing things wrong in the first place.

I stopped doing all that daft pooling stuff from my second game onwards - and yes, rarely every now and again, it drops a frame doing a GC - but my code was so much easier and quicker to develop I'll never look back.

Cas :)
GC in Java has the main goal of staying out of your application's way. It does work 95% of the time, but there are things you can do make sure that your code doesn't do bad things when GC happens.

First, don't write a finalize() method in any of your classes. This method is run by the GC right before it deletes the object. You can have this method do things like close files and sockets. The big problem with this is 1) the GC is executing your code and you dont know when that is going to happen; and 2) When the GC executes your code the object is now 'alive' and not a candidate for garbage colletion. So the memory it is using will not get released from the heap until the next GC pass. Bottom line is finalize() is bad Java (as far as GC is conserned) and you need to refactor it out if you are using it.

Second thing you can do is keep you objects short lived. This goes against what daireq says above, whom I humbly disagree with. In the HotSpot VM the heap is divided into two areas: Eden and Old. Each area uses a differnt GC algorithm which is executed only when the effected area is full. Eden is small, Old is large. Eden is where your objects get instantiated. When Eden fills up, GC is run and any live objects are moved to one of two survier spaces on the heap, all others are deleted. The deletion in Eden is very fast (less than one machine cycle per object deleted!). Bottom line is if you can kill your objects in Eden then GC is almost free. Objects that live thru GC in the surviver spaces eventually get promoted to the Old space.

In the Old space GC happens much less frequently than in Eden (hopefully) because it is bigger. However, since it is bigger, CG takes longer. Like in Eden, GC only happens when the area is full. If GC happens in the Old area you are likly to notice it.

There are very good times to use a pool of pre-created objects, like dairq suggests, and that is if the objects are very expensive to construct. Database connections over a network and sockets are a good example. However, using a pool like this will mean that all those objects will live in the Old space causing it to potentially fill up faster. That means GC in the Old space may happen more frequently.

In general, creating a new object is very fast (10 machine cycles for an empty constructor in the HotSpot VM). Most constructors in the Java API are very light and fast like that, but some aren't. Read the documentation carefully if you think you are creating an expensive object and benchmark the object's creation if you think your code is spending too much time in there. For constructors that you create, try to keep them light and fast.

Hope this helps!
steelmtn98 is correct. Those object pooling tricks that used to work on the older JVMs are no longer required.(Especially since 1.3). There is a very good article that explains this at http://www-106.ibm.com/developerworks/java/library/j-jtp01274.html
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Quote:Original post by steelmtn98
Second thing you can do is keep you objects short lived. This goes against what daireq says above, whom I humbly disagree with.


No Worries ! Very informative post, thanks. I've never really looked into the mechanics of the GC, having found on numerous occasions that if you let it alone it does its job quite well for the most part. Obviously some of my notions are a little outdated, so all the more reason not to worry about it at all !

D.

Cool, cool, thanks for the complements. I just read an article on GC so it was fresh in my mind. Glad I was able to pass it along.
Oh and another thing: if you're worried about it run your game with -verbose:gc command line switch - then you can really see what it's up to!

Cas :)

This topic is closed to new replies.

Advertisement