1.7 G1GC significantly slower than 1.6 Mark and Sweep?
John Hendrikx
hjohn at xs4all.nl
Tue Apr 26 07:59:01 PDT 2011
Hi list,
I've been testing Java 1.6 performance vs Java 1.7 performance with a
timing critical application -- it's essential that garbage collection
pauses are very short. What I've found is that Java 1.6 seems to
perform significantly better than 1.7 (b137) in this respect, although
with certain settings 1.6 will also fail catastrophically. I've used
the following options:
For 1.6.0_22: -Xms256M -Xmx256M -XX:+UseConcMarkSweepGC
For 1.7.0b137: -Xms256M -Xmx256M -XX:+UseG1GC -XX:MaxGCPauseMillis=2
The amount of garbage created is roughly 150 MB/sec. The application
demands a response time of about 20 ms and uses half a dozen threads
which deal with buffering and decoding of information.
With the above settings, the 1.6 VM will meet this goal over a 2 minute
period >99% of the time (with an average CPU consumption of 65% per CPU
core for two cores) -- from verbosegc I gather that the pause times are
around 0.01-0.02 seconds:
[GC 187752K->187559K(258880K), 0.0148198 secs]
[GC 192156K(258880K), 0.0008281 secs]
[GC 144561K->144372K(258880K), 0.0153497 secs]
[GC 148965K(258880K), 0.0008028 secs]
[GC 166187K->165969K(258880K), 0.0146546 secs]
[GC 187935K->187754K(258880K), 0.0150638 secs]
[GC 192344K(258880K), 0.0008422 secs]
Giving the 1.6 VM more RAM (-Xms1G -Xmx1G) increases these times a bit.
It can also introduce OutOfMemory conditions and other catastrophic
failures (one time the GC took 10 seconds after the application had only
been running 20 seconds). How stable 1.6 will perform with the initial
settings remains to be seen; the results with more RAM worry me somewhat.
The 1.7 VM however performs significantly worse. Here is some of its
output (over roughtly a one second period):
[GC concurrent-mark-end, 0.0197681 sec]
[GC remark, 0.0030323 secs]
[GC concurrent-count-start]
[GC concurrent-count-end, 0.0060561]
[GC cleanup 177M->103M(256M), 0.0005319 secs]
[GC concurrent-cleanup-start]
[GC concurrent-cleanup-end, 0.0000676]
[GC pause (partial) 136M->136M(256M), 0.0046206 secs]
[GC pause (partial) 139M->139M(256M), 0.0039039 secs]
[GC pause (partial) (initial-mark) 158M->157M(256M), 0.0039424 secs]
[GC concurrent-mark-start]
[GC concurrent-mark-end, 0.0152915 sec]
[GC remark, 0.0033085 secs]
[GC concurrent-count-start]
[GC concurrent-count-end, 0.0085232]
[GC cleanup 163M->129M(256M), 0.0004847 secs]
[GC concurrent-cleanup-start]
[GC concurrent-cleanup-end, 0.0000363]
From the above output one would not expect the performance to be worse,
however, the application fails to meet its goals 10-20% of the time.
The amount of garbage created is the same. CPU time however is hovering
around 90-95%, which is likely the cause of the poor performance. The
GC seems to take a significantly larger amount of time to do its work
causing these stalls in my test application.
I've experimented with memory sizes and max pause times with the 1.7 VM,
and although it seemed to be doing better with more RAM, it never comes
even close to the performance observed with the 1.6 VM.
I'm not sure if there are other useful options I can try to see if I can
tune the 1.7 VM performance a bit better. I can provide more
information, although not any (useful) source code at this time due to
external dependencies (JNA/JNI) of this application.
I'm wondering if I'm missing something as it seems strange to me that
1.7 is actually underperforming for me when in general most seem to
agree that the G1GC is a huge improvement.
--John
More information about the hotspot-gc-use
mailing list