JVM is functioning very differently with same flags

157 views Asked by At

I created test application (with Sheduler inside that runs every 20ms, there are reads/writes to DB) and deployed it on Glassfish server on two different PC. Both have same (copy from one PC to another) Glassfish (both have also latest JAVA version) server with following flags: -XX:+DisableExplicitGC, XX:MaxGCPauseMillis=200, -Xmx512m, -Xms512m, -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC, -server...

First PC has 8GB of RAM, i5 CPU (2.5 GHz) with WIN 8.1 64bit OS.

Here is the graphical presentation of GC log of first PC (after 30 hours): enter image description here

As you can see GC Peformance is around 12000 MB/s, throughput is 99,93%, minor GC pauses are around 20ms long and they occur every 30 seconds. There was na major GC at this time (but it happened 8 hours later). In the first 30 hours old generation increased from 90 MB to 160 MB.

The second PC has 1GB of RAM, Athlon 64 X2 (dual core) CPU AND WIN XP 32bit. Here is the graphical presentation of GC log of second PC (after 30 hours): enter image description here

As you can see GC Peformance is around 4000 MB/s, throughput is 99,91%, minor GC pauses are around 100ms long and they occur every 50 seconds. There was na major GC at this time (it still didn't happen after 4 days). In the first 30 hours old generation increased from around 70 MB to 75 MB.

My question here is: why is promotion to old generation in second case much smaller than in the first case? This mean that major GC won't be triggered quite some time (maybe never) when major GC in first case was triggered after 40hours. Application is doing same things in both cases so I don't get it why JVM is functioning so much differently with same flags. I don't know what are benefits in the first case (more object promotion to old generation) if that means that major GC have to occur when in the second case major GC won't have to occur. What is benefit of promoting from survivor space to old generation if application on both servers is performed at the same speed (write to DB every 20ms and then some read from same DB tanle). Also minor GC in the second case are more rarely (50 seconds) than in the first case (30 seconds). I would expect than better PC would have much better results but now I don't even know which one is better... Only major advantage of first case is higher GC Performance speed so minor GC are done faster. Thank you all for clarify why it is done so as it is.

1

There are 1 answers

3
the8472 On BEST ANSWER

I would expect than better PC would have much better results but now I don't even know which one is better...

Better is subjective. Depending on whether you need throughput (fraction of CPU cycles spent GCing), sustainable allocation rates, low pause times or low footprint. Generally there's a tradeoff between those goals.

G1GCs is a complex, selftuning beast that behaves differently under different circumstances. So unless there actually problematic behavior which you want to avoid, where's the problem? It just does its job differently.

As mentioned in the comments, if you merely wish to satisfy your curiosity, you can compare VM flags by appending -XX:+PrintFlagsFinal to the options and run a diff. They are probably quite different because 32bit and 64bit systems get different defaults.