Turbo-charging JavaTM HotSpot Virtual Machine

New article on tuning HotSpot from java.sun.com

http://developer.java.sun.com/developer/technicalArticles/Programming/turbo/

thanks for the link, until I can read it all I thought I’d mention how I turbo-charge my JVM. I use the -XX:+PedalFaster and/or -XX:+SquirrelGC . ;D Ok, back to work.

lol.

If I read that article correctly, no matter what happens there is ALWAYS a stop-the-world phase during garbage collection… and it ALWAYS seems to take a huge amount of time.

If this is true, :o

For the gaming community what can we do to minimize this impact? Any thoughts? And no, I don’t mean simply just using -Xincgc, I figure that’s the first thing we try… I mean more aggressive techniques.

Yes, we can. We have to write games that are appropriate for Java. And maybe these are not maximum-framerate games running in a tight loop.

Make your gameloop do whats needed - and then go to sleep(). Give the JVM some time to breath.

Thats also the way Java3D is meant to operate.

To my experience a Java program will never run smoothly if you overcommit the primary gamethread. Even Java3D apps can run smoothly if not WakeupOnElapsedFrames(0) but WakeupOnElapsedTime( aGoodValue ) is used to drive the game.

In my prototype, I have an FPS slider. If you put it to 30, everything is smooth, if you goto 80, you experience teh stop-the-world phase!

Or alternatively just sit back while swapBuffers puts your thread to sleep for you in GL :slight_smile:

And don’t be allocating any objects in your rendering loop.

Create them all at game init and level init, and recycle them. It’s nearly guaranteed to get rid of the pauses but at the expense of a little complexity. But the C/C++ crowd have been doing this for years because malloc and new are so inefficient.

Cas :slight_smile:

… ending up with good-old C programs written in Java - only slower…

Java w/o new is real hard stuff. And I’m afraid that even if you do it yourself, other libs and threads will do it for you.

Java3D? Collections? IO? Events? AWT?

I wouldn’t advocate programming without new, but one should be very keen on avoiding it whereever possible!

I run an old dual p2/333 at home and I must say the new concurrent collector does wonders. I have been able to almost totally eliminate any gc pauses. Every once in a while you notice a slight hitch when it does a full pass but other than that it is very smooth. I have read in a couple places that 1.4.2 and 1.5 will give us many more gc options so for the next few months I am going to be very optimistic.

In my (extremely limited) experienced writing some timing-critical drawing routines, I’ve found that the best way i’ve managed to eliminate garbage collection is to create state-objects that are created once and maintain the state of things for various operations, and also have ‘init’ methods on them when I need to reset them for another action…I donno if that makes sense, but basically the point is that instead of re-creating objects (that will be needing to be garbage collected later) I define objects that I can modify values of and reuse the memory instead of creating whole new objects again (I do this sort of thing with my line interator class (search the old forums) and it allowd me to traverse a series of points with no object creation.

With the single-threaded nature of most games, you won’t need to worry about your state object being mucked with when you aren’t looking (if you write in a single-threaded archietecture).

I think the number one rule in high performance game programming is zero garbage collection (if possible). Even if that means resorting to pooled objects that are placed in a pool and used and then put back into a pool (but the pool objects never go away) you don’t tax the garbage collector…I wonder if the garbage collector is smart enough to realize that if there’s no object creation since it’s last sweep, it has no work to do.

-Chris

I believe that using the standard collector options you will see absolutely no garbage collection at all if you don’t call new.

Cas :slight_smile:

Hooray for System.gc() :slight_smile:

Well I have been experimenting with adaptive heuristics in 3d scene rendering and to tell the truth the sight isn’t pretty.

Getting an adaptive oct/quadtree to run in a tight loop is almost impossible, since there is no way to flag objects to be deleted in the next cycle.

One thing i’d like to see in the garbage collector is user-ability to flag objects to be deleted in next garbage collection run, for example

Node child[4] = new Node();

do node stuff, nodes 3 and 4 were required in the last loop, but now they are obsolete since the scale changed.

System.flagToDelete(node[3]);
System.flagToDelete(node[4]);

node[3] = null;
node[4] = null;

:slight_smile:

Actually I assume you mean to give objects directly to the collector so it doesn’t have to find them itself… the thing with that is that the collector must still verify that there are no references to the objects any more… so it has to do all that ‘finding’ work anyway to prevent potential access to collected objects.

In other words… Your idea won’t work :frowning:

Maybe this is a case where Object pooling would work?

Don’t flag objects for deletion… put them back in the pool to be recycled.

Depending on various factors, object pooling can pay off. But in general it is discouraged as it makes more long-lived objects for the collector. If you can keep all of your per-frame objects in the ‘short-lived’ (‘nursery’) part of the Java heap then maybe you can get away with a few 'new’s per frame.

As palmer said it won’t work, however I don’t know enough about the GC to discuss about this matter

I’m currently running with pooling. It is not the most elegant way to do it, but more a cheap alternative that eventually costs more than the more expensive route. However, pooling is more more expensive than doing non adaptive map, where the initial point of adaptivity gets trashed. So basically a static quadtree is just better.

Adaptive lod on the otherhand is not a problem the way I see it. As long as i’n using simple types, such as floats, there won’t be a big hit in performance, since if I have 600 nodes with 7 sub divisions that will be only few hundred new objects and actually I’m not even newing the object, just changing the content.

Im a bit confused as to the goal here.

AFAIK you shouldnt reallty care when thinsga re colelcted so long as you always have cheap memory available for you current
operations.

if you are keeping objects referenced for only 1 frame at a time then again FWIK it should never escape the newsapce, where allocation and collkection are very cheap. (Arguably as cheap or cheaper then the work invovled in managing a pool.)

It is possible yo uare creating so many object thats you are thrashing the new space and causing object to prematurely progress to the next generatioon. There is an -XX falg for adjusting the size of the new space (and given time, HS will make adjustments on its own.)

Another article, all about the garbage collectors available as of 1.4.2, and how to tune them to your bidding (at least as much as we can). Detailed examples of when to, and when not to use particular collectors, and good tips on how to optimize each collector for a specific task. The moral here? Work with the collector and don’t assume right away that it is your enemy (though it may turn out to be so anyway).

This surely duplicates some information found in the article that started this whole thread.

NOTE: At the bottom of the article is a link to a useful FAQ.
http://java.sun.com/docs/hotspot/gc1.4.2/index.html