Garbage Collection

I’m seeing several attempts to optimize for avoiding garbage.
I have run some microbenchmarks on Openjdk 7, and found some of the usual assumptions to be untrue:

  • It’s irrelevant whether you generate much or little garbage (supposedly because it’s a moving collector, so the overhead is O(number of live blocks))
  • Memory pools don’t help, they can even hurt
  • Tricks to force variables on the stack sometimes make a difference, mostly they don’t.

I’m aware that much of that GC lore is from 1.4 times and earlier, where the GC was of substantially lower quality, so these results didn’t come as a complete surprise.

What I’m worried about is how much of these findings can be transferred to other situations:

  • different platforms
    -. different JVM implementations
    E.g. I hear that some Dalvik versions have a really sucky GC. That doesn’t concern me much (I don’t target Android anyway), but of course I’m a bit worried about hitting and older or somehow out-of-whack JVM where performance would suddenly differ sharply.

Do we have any data on this? Links, tables, measurements, benchmarks?

Its hard to measure as you can’t predict what the JVM does. The best is to have methods that create a lot of young generation objects be small and often called, then they run hot quickly and the “garbage” effectively turns into stack variables that cause no garbage at all. Generally its best to demand a good JVM really because what the JVM can do is magnitudes above what you can do as a programmer, and in many cases what you do even hurts as you found out because a JVM expects “normal” Java code it can make efficient. “Tricks” might in fact delude the JVM into creating less efficient native code. So its generally best to determine this with an actual use case instead of artificial test setups, if it works it works and if theres special bottlenecks on certain platforms they have to be addressed. The fact that we want to find (and probably already did in avian) a JVM that can create native code and would work on multiple platforms might alleviate that situation in the future.

For direct memory, which jME uses a lot, the things are even different. The implementations are even more special but most react in such a way that the native data doesn’t really trigger any thresholds in the JVM so they are only cleaned out very lazily. Its best to have a relatively small java heap size compared to the native heap size to cause GC calls to happen due to java memory earlier than they would have to happen for direct buffers. We added helper methods though that use the native methods of most JVMs via reflection to clean these manually which proved to work quite well.

The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless theres emotes that hint otherwise or theres an increased use of exclamation marks and all-capital words.

1 Like

JME tries to be “memory stable” in the render loop. Apparently, Android is still really bad at GC of young generation objects. In general, I’m the one on the core team that finds this the most distasteful, I think. Java has been really good at collecting of “young generation” since some versions of 1.5 and any version since 1.6. It makes my stomach hurt a little to have to resort to these decade-old tricks.

However, there are cases where it makes good sense… and others where the final solution is actually faster anyway. SafeArrayList is one of those cases. It bugged me that a) we couldn’t do simple iteration, and b) that the lists were really fragile. In the end, we got a list that can be modified during iteration and also allows us to iterate right over the underlying array. This incurs less garbage and is also significantly faster (in microbencmarks) than either plain List iteration or doing for( i = 0; …) list.get(i) style iteration.

Also, in some cases, it’s not about the garbage generated but the time taken to create the objects in the first place. I’m also an anti-fan of TempVars but there are cases where that makes good sense also.

…and on Android, it’s apparently all significant. Hopefully generational GC catches up there someday.

Are there docs somewhere that tell us what versions of Android are having a bad GC?
In case I ever target Android, I’d probably want to write something like “runs on anything that has a Java lookalike, except on Android before version x.xx” - I don’t know what to put in for x.xx though, so I need some info to go by.

@normen said: The fact that we want to find (and probably already did in avian) a JVM that can create native code and would work on multiple platforms might alleviate that situation in the future.

Search no more, it’s done: http://vmkit.llvm.org/

It comes with a few caveats:

  1. It uses the Gnu Classpath libraries, not Openjdk. That’s unfortunate because there are incompatibilities, i.e. code running fine on Openjdk might hit bugs in the Gnu libraries. Might be less bad than it sounds though, Vmkit has been successfully used to run Eclipse and Tomcat. The Vmkit guys have posted a port to Openjdk as an “interesting project”, i.e. they would be happy to see it done (but probably won’t do it by themselves).
  2. There is no useful IDE support. You can’t check whether it works while developing, the best you can do is to use it to optimize a build before shipping it to testers and end users. Not a problem unless you hit a bug in Vmkit, at which points things start to suck badly (not a high risk if it runs Eclipse and Tomcat just fine, but still a point worth considering).
  3. It leverages a different GC (Mmtk). It looks pretty solid actually (all the right buzzwords are in place), I just don’t know how well-tuned it is.

Looks good enough to try it out as an end-of-pipe optimizer, but I wouldn’t bet a project on it - it looks a bit too underfunded for that.

Yeah really, android Dalvik VM is nowhere near others VMs around. Unfortunately there are lot of optimizations in the engine that are here only for android, and make no sense for desktop…

@nehon said: Yeah really, android Dalvik VM is nowhere near others VMs around. Unfortunately there are lot of optimizations in the engine that are here only for android, and make no sense for desktop...

…but generally don’t harm desktop either except making the code messier. :slight_smile:

@toolforger: Avian works fine and even better it works with the openjdk classpath. All those java crosscompilers and VMs look nice until you ask about java API compatibility ^^ Also theres no need to bet anything, theres plenty choice.
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless theres emotes that hint otherwise or theres an increased use of exclamation marks and all-capital words.

Ah, I thought that “avian” was a typo for “in vain”, so I totally misunderstood you.
It’s a JIT compiler though, so it’s not different from Openjdk in this respect.
Might still be useful for bundling jars up as an executable, so it’s bookmarked anyway.

@toolforger said: Ah, I thought that "avian" was a typo for "in vain", so I totally misunderstood you. It's a JIT compiler though, so it's not different from Openjdk in this respect. Might still be useful for bundling jars up as an executable, so it's bookmarked anyway.
Its also a binary compiler, I successfully compile iOS binaries (.a files I can import in XCode) for jME applications with it: http://hub.jmonkeyengine.org/forum/topic/alpha-ios-deployment-available-in-sdk-please-test/ Thats the beauty of it :) We could even use it to go to PS3 if somebody paid for the dev kit ^^ The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless theres emotes that hint otherwise or theres an increased use of exclamation marks and all-capital words.
@normen said: Thats the beauty of it :) We could even use it to go to PS3 if somebody paid for the dev kit ^^

I hope to have that kind of money someday. I’d love to play Mythruna on a PS3. :slight_smile: