views:

404

answers:

3

I've just tried the -XX:+DoEscapeAnalysis option enabled on a jdk6-u18 VM (on solaris) and had a rather disappointing experience. I'm running a scala application which has rather a lot of actors (20,000 of them). This is a recipe for garbage-creation!

Typically the app can run with 256Mb of heap but generates huge amounts of garbage. In its steady state it:

  • spends 10% of time in GC
  • generates >150Mb of garbage in <30s which then gets GC'd

I thought that escape analysis might help so I enabled the option and re-ran the app. I found that the app became increasingly unable to clear away the garbage it had collected until it seemed eventually to spend the entire time doing GC and the app was "flatlining" at its full allocation.

At this point I should say that the app did not throw a OutOfMemoryError which I would have expected. Perhaps JConsole (which I was using to perform the analysis) does not properly display GC stats with this option on (I'm not convinced)?

I then removed the option and restarted and the app became "normal" again! Anyone have any idea what might be going on?

+6  A: 

1 Did the escape analysis show up as being enabled in JConsole? You need make sure you're running the VM with the -server option. I assume you had this working, but I just thought I'd check.

2 I don't think escape analysis will help the situation with Scala Actors. You might see a big gain if you do something like:

def act():Unit = {
   val omgHugeObject = new OMGHugeObject();
   omgHugeObject.doSomethingCrazy();
 }

In the example above the EscapeAnalysis would make it so omgHugeObject could be allocated on the stack instead of the heap and thus not create garbage. I don't think it is likely that the escape analysis will help with actors. Their references will always "escape" to the actor subsystem.

3 Are you on the most recent release of Scala? There was a memory leak that I believe was fixed in a recent version. This even caused Lift to spawn off its own Actor library that you might look into.

4 You might try the G1Garbage collector You can enable it with:

-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC

Steve g
If it's objects being transferred from one thread to another, not only is stack allocation going to be impossible I guess there will also be problems with Thread Local Allocation Buffers (TLAB). I believe the JRockit JVM is even more aggressive with its thread-local memory behaviour.
Tom Hawtin - tackline
I'm not expecting the escape analysis to be able to help with the actors *per se*, but there are plenty of other implicit conversions going on in the app on the stack which could be elided. I was just hoping to make some kind of dent in the GC overhead!
oxbow_lakes
The trouble with G1 is that it's impossible using JConsole to actually see what is going on
oxbow_lakes
Yes - heap analysis was enabled. I don't need `-server` because I'm running on a solaris monster so the JVM is a server one by default. Yes, I'm using scala 2.7.7.
oxbow_lakes
I'm accepting the answer because I now think that something else is going on; I'll ask a separate question
oxbow_lakes
Escape analysis has been disabled: http://stackoverflow.com/questions/2179830/experiences-with-escape-analysis-enabled-on-the-jvm/2183956#2183956
Seun Osewa
Try jdk6u21. Escape analysis has been reenabled
Seun Osewa
+3  A: 

I suggest you try to increase the new generation size, e.g. -XX:NewSize=96M XX:NewRatio=3. Use JVisualVM (included in the JDK), with the Visual GC Plugin to watch how the young and old spaces are utilised.

retronym
Yes - I tried this and it made hardly any difference whatsoever. I tried ratios ranging from 1 to 4
oxbow_lakes
+4  A: 

from the jdk-u18 release notes:

Note that Escape analysis-based optimization (-XX:+DoEscapeAnalysis) is disabled in 6u18. This option will be restored in a future Java SE 6 update.

llemieng