Garbage Collection (programming java C Style)

Hi i am new to the forum, and “new” to desktop java games…

i read a thread that looked very interesting, and i especially enojoyed this particular post by Mithrandir :
http://192.18.37.44/forums/index.php?topic=10445.msg83698#msg83698

This part alerted my curiosity: … “One of the tricks to get Java code running fast is to write it like it was C code. This is a point I continually make here and yet you get people that claim that garbage collection is good and fast. The fact is that it isn’t.”

So how does one bypass the garbage collector? and controls memory in Java to obtain the same results in terms of performance? (Is there any guidelines, articles) and is this the common practice amoung java game programmers?

Thanks,
Dan

You do it by not creating garbage, but if you are on the Sun server VM 1.5 or later I absolutely dispute Mith’s claim that this is necessary. It used to be, but it isnt any longer, at least with the Sun VM.

Last GDC I wrote an entire fake Socket stack for our demo that created plenty of garbage for every packet sent or recieved. Running under an app sending 15 or more sends and 60 or mreo receieves a second we saw NO GC pauses at any time during exection the entire show. My current project, JNWN, is getting 250fps on my laptop with NO special handling or pooling of objects. In fact we are currently seeing performance improvements from packages such as Java3D by removing obejct pooling code we were previously using!

These days trying to fight creating garbage falls into the “premature optimization” category, which is always a bad thing.

Write clear, clean well encapsulated code and don’t worry about short-lived objects. So long as you don’t make them persist past the eden space they wont cause you any harm.

When you DO have a GC problem, start by profiling like you do with any other problem. Chances are your problem isnt what you think it is.

I havn’t had an issue with the GC since the days of 1.3 and Java3D. Unless you’re creating and destroying about a billion objects a frame I doubt you’ll see any noticable effect.

I can back this up.
Previously I did some premature optimizations by pooling objects in my game Cosmic Trip. Later I took that out completely, resulting in lots of added garbage (and I checked this) but not perceived performance loss or GC stuttering whatsoever, even in Java 1.4.
Recently I did a change in my emulator JEmu2 to save memory. This change also added more garbage to be created: every memory read/write now creates a temporary object and there are lots of reads and writes done every frame. Again, absolutely no performance loss, no perceived GC side effects, and the change did save about 130MB in one extreme case.
I’m not saying Mithrandir is telling bullocks but I wouldn’t take his experience as a guide for anyone to follow. Like Jeff said, write clean code first. It’s always easier to refactor and optimize clean code than prematurely optimized code. Chances are that if you prematurely optimize, you optimize something that doesn’t need optimizing.

Then please tell your employers to provide the Server VM as standard :slight_smile:

Last week we published a game that in early release was unplayable on a 3Ghz 1Gb machine because of the insane amounts of GC. IIRC (Kev will correct me if completely wrong :)) ceasing to over-allocate objects (bad code, not ours, 3d party) enabled it to run perfectly on 1Ghz machines with 0.5Gb RAM.

That’s a pretty huge difference for GC problems, and you’re telling me we wouldn’t even have seen them if we’d been using the server VM? Yet, getting people to run the server VM is still hard. For instance, has sun got around to actually distributing it to Windows users yet, or is it still only included in the JDK?

I see that it still does not automatically use the server VM unless the user’s “machine is one with at least 2 CPUs and at least 2GB of physical memory.” - and never at all in windows unless the user has an AMD-64. Riiiight. (http://java.sun.com/j2se/1.5.0/docs/guide/vm/server-class.html).

AFAICS, the status quo is that GC is still “a major problem” in Sun’s JVM not “a fixed issue”, and it will remain that way until the actual JVM that most people are using all the time fixes it, NOT merely when a different VM they have to manually enable fixes it.

NOTE: this is despite the fact that - in general, with java 1.4 - like everyone else, I’ve had no problems at all. Maybe it’s a java 5 problem?

Good Start - The above is actually correct :slight_smile: It was an extreme circumstance tho, larges amount of vertex data being generated every frame - not just 3rd part code but at least partly my assumption of how the code would work (given there was no javadoc :))

That said, I don’t think GC for the general game case is a problem. However, that’s not a reason to just go off and write anything because it looks pretty. I’ve found in the past that quite often the memory use ignorant solution is often not the fastest/most elegant/appropriate anyway.

Of course the rule still applies, you write your code how you want it to be - then profile - if you get problems then work it out. You simply can’t predict whats going to happen under the hood anymore, the system just has to many variables for the average mind to determine. Which is exactly what we did with the game mentioned above, code, test - fix.

Code is beauty etc.

Kev

Two comments…

(1) We’re working on it, thats what the two-stage VM is all about ;D

(2) “Insane” amounts of anything is likely to cause trouble. Thats why I told the poster “IF” he has a problem the next step is to profile and tune ;D ;D ;D

Likely the imapct woudl have been significantly smaller but, as I say, insane amounst of anything is bad. Thats sorta what “insane” means…

Hmm. Thats odd and unclear. let me ask the VM guys.

I do nothing special launchign my app.

Which means, if this is true, Im getting 250fps and no garbae problems from client VM. That would be awesome but I find it a bit hard to believe at first…

If you have seen a reproducible decrease in acceptable GC from 1.4 to 1.5 you should defintiely bug report it.

I actually use 1.6 (Mustang) in beta these days myself.

OK so I conclude that it is not the standard approach to programming j2se games,

I have programmed j2me games and also j2se applications but i am used to do game programming in C++, I will code as I would a normal j2se application and then profile it and “optimize”, I just wanted to check if I was not falling into a performance trap. Early optimization is usually a bad thing, but being new to the block I thought it would be of good tone to actually ask more experienced people aka Gurus :wink:

Got my answers, thanks for the tips.

BBB is right.

My comments on JNWN performance are in re Mustang (1.6) client VM ;D

So client VM is also doing an excellent job of gc-ing now.

Damn. Gotta love those VM guys.

I use 1.5 for my current game and had a lot of problems with gc (client vm)… the game would stutter every 3 or 4 seconds…

now when using pooling, and almost not creating any garbage it runs as smooth as anything… no gc stutter anymore… :slight_smile:

so for me… I definetely needed to use pooling and stuff… and even if it wouldn’t stutter without, I can’t imagine getting performance improvement for not using pooling (at least for my game)… I just can’t see creating new objects all the time being faster than reusing already created objects…(It could be on par with a good vm… but not faster…)

And using pooling doesn’t mean writing unclear and sloppy code… (as some people seem to think)… just make sure you plan it good, and that you are very sure about at which points you free objects (letting them enter the pool)… and where you reclaim them…

… and if you plan for it early on… it’s very easy to create methods to turn on or off the pooling. Just make sure that you have to call a certain method to get a new object (not using constructors)… then with pooling enabled it will take an object from the pool, when disabled it will create a new object. This wont take much extra time if you do it when starting coding… but optimizing after you’ve run into trouble with gc might take you alot of time… (so I don’t agree to always just code along making the code look pretty and don’t worry until profiling… with a bit of planning you could save alot of time…)

Hum… I get your point, thanks for the tip Aramaz.

[quote]I use 1.5 for my current game and had a lot of problems with gc (client vm)… the game would stutter every 3 or 4 seconds…
[/quote]
Did you try to tune the GC before you went to pooling?
Some object pooling is already going on ‘under the hood’ and in my experience this usually works well enough. If it doesn’t, playing with the GC tuning parameters can help even more.

But, you do have a point. By doing the pooling yourself, you rid yourself of any dependency to some smartness of a particular VM.
I guess much depends on what kind of objects you are creating/pooling; if you have to create/destroy many ‘heavy’ objects, pooling can make sense.

My quick 2p:

  1. Alien Flux creates almost no garbage whatsoever, at the expense of having a rather complicated pooling system for particles and other objects that tend to get created and destroyed a lot like player lasers. I wrote that, er, 2 or 3 years ago or something.

  2. Ultratron has no pooling whatsoever and creates just as many particles and sprites. The code is almost trivially simple to understand compared to the Flux code (you can see that for yourself if you look) and I’ll be damned if I can see any difference.

  3. If you have a finalizer anywhere you bugger GC good and proper so make sure you’re not creating stuff with finalizers. Similarly WeakReferences etc. are far more complicated to handle so avoid using them if you can.

  4. As Jeff says, just because you don’t have to think about it doesn’t mean it’s not free: every tiny bit of garbage you produce requires a tiny bit of CPU to clear up later.

  5. Optimising GC before you’ve actually finished writing the game is like eating pudding before you’ve had your dinner.

Cas :slight_smile:

Since we were dealing with 3rd party code, I spose there’s a chance this could have happened?

hoho… since everyone here seemed so sure I had to go test to turn off pooling again…

and guess what… no stuttering!.. I was proved wrong… (at least when I’m the only one playing… it remains to be tested with many players logged in…)

It was a while ago when I implemented pooling… back then I had a lot of stutter… I was running with the default configuration of memory and gc when I started out. Then when I implemented pooling most of the problems went away…

some time later I found the flags to optimize the gc and memory use (still had some stutter but only very occasional back then)… ( -Xmx32m -Xms32m -XX:+UseConcMarkSweepGC -XX:NewSize=1000k -XX:MaxNewSize=1000k is what I use now)…

Of course by then I’d already implemented pooling… and never thought to try without again… so you can happily disregard the things I said before… :slight_smile:

I like to eat pudding before dinner… :wink:

WOW… this thread just shows me how immature the java game field is, there are no “de facto” or “de jure” rules, it would be nice to have a white paper or a nice article series about creating “Best Practicies” in the field, like the ones you get from the Effective C++ book series and Game Gems series.

The amount of contradictory or parametrized (as in you have to change certain VM parameters to get the performance) information is overwellming, and confusing.

Do any of you write articles (or white papers), to explain this in a clear (theory and simple examples) way?

Is there any publication (or website) dedicated to java game programming (tricks/gems)?

All the best,
Daniel

You’re reading it.

And many of the people in here are probably the world’s most experienced experts in this particular field (not that I’m blowing me own trumpet or owt, but it’s true). So ask away! And weigh the answers.

Cas :slight_smile:

How does your confusion make the entire java game field so immature?
For example, to get performance the most well known ‘best practice’ is to write clean code first, then profile, then optimize. Tuning the VM can sometimes be part of the optimization process, comparable to changing optimization parameters in a C++ compiler.
Of course there are many shades of gray which might sometimes lead to some contradictory, whichever development environment you use.

That said, of course java is not as mature as C++ as a game development environment, but C++ has been around a lot longer so that isn’t really surprising.

erikd: I did not intent to attack, just stating a fact… I read many books and articles, so it is a bit of a surprise (to me) that the most common mistakes and pitfalls for java desktop game programming have not been resolved into a set of best practices (tricks or gems) like in the many c++ publications in the form of book or magazine article.

Also if you look at the general app J2SE field there is already allot of best practices. Game programming is a less mature field of the java panorama, only after jdk1.3 with HotSpot (if I am not mistaken) did it become technological feasible to produce a good quality java game, that was 5 years ago, so I was expecting to see more in the field of best practices and commonly accepted techniques, tricks and gems.

Having had experienced people (you guys) kindly reply to my thread i can see that there is not as much “unwritten/unofficial” rules for Java Desktop Programming as i would expect, or an unofficial/unleashed guide to java desktop game programming.

To All…
I am new to the java desktop game field, i do come from a C/C++ background but i am not a purist and i don’t want to start any useless discussion about languages (C++ vs Java) it is simply a waste of time both have it’s pros and cons, i refuse to get into that kind of discussion.

I am here to learn with you all, most of you are pioneers, i love that feeling of being the first to find out a way to do something or brave into unknown or uncharted territory, i am only beginning so I have much respect and admiration for all of you and kindly thank you for receiving me into your ranks, with time i hope to climb the latter to the top, and earn your respect in return.

I understand that from time to time there will be some hotter discussions, some unkind remarks, some open flame wars, such is the nature of the best… (it always happens in web forums).

I like to read structured information in the form of books and articles (admitting to the static nature, they tend to be more organized and well thought than web forums), but from your replies i can see that this is the best source of information on the subject and that i am in the right place, talking to the right people ;D