Runtime Commited Heap Resizing
Join the DZone community and get the full member experience.
Join For FreeWe used to update minor Java versions mostly due to security issues. But sometimes those minor updates brings us brand new, awesome features. So was for example with 7u40 which brought us awesome Mission Control known from JRockit. (If you are interested in tracking changes across Java updates take a look at
http://www.oracle.com/technetwork/java/javase/8all-relnotes-2226344.html for Java 8 orhttp://www.java.com/en/download/faq/release_changes.xml for Java 7)
Same situation is now with versions 7u60 and 8u20. Since now flags MinHeapFreeRatio andMaxHeapFreeRatio became manageable, which means we can change its values... in runtime :)
You can always check which flags in JVM are manageable by invoking
java -XX:+PrintFlagsFinal -XX:+UseG1GC -version |grep manageable intx CMSAbortablePrecleanWaitMillis = 100 {manageable} intx CMSWaitDuration = 2000 {manageable} bool HeapDumpAfterFullGC = false {manageable} bool HeapDumpBeforeFullGC = false {manageable} bool HeapDumpOnOutOfMemoryError = false {manageable} ccstr HeapDumpPath = {manageable} uintx MaxHeapFreeRatio = 70 {manageable} uintx MinHeapFreeRatio = 40 {manageable} bool PrintClassHistogram = false {manageable} bool PrintClassHistogramAfterFullGC = false {manageable} bool PrintClassHistogramBeforeFullGC = false {manageable} bool PrintConcurrentLocks = false {manageable} bool PrintGC = false {manageable} bool PrintGCDateStamps = false {manageable} bool PrintGCDetails = false {manageable} bool PrintGCTimeStamps = false {manageable} java version "1.8.0_20" Java(TM) SE Runtime Environment (build 1.8.0_20-b26) Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)Getting back to our flags. MinHeapFreeRatio defines minimum percentage of heap free after GC to avoid expansion, while MaxHeapFreeRation (as you can expect) describes maximum percentage of heap free after GC to avoid shrinking.
Now let's see how this heap resizing works. At first we need to find java process right for testing. I'll going to use running IntelliJ IDEA.
As you know java pids can be found by invoking jps command:
jps -l 17136 com.intellij.idea.MainWe already know our testing pid, so it's good time to find out some heap statistics. We'll use jmapcommand to do that:
jmap -heap 17136 Attaching to process ID 17136, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.20-b23 using thread-local object allocation. Garbage-First (G1) GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 2147483648 (2048.0MB) NewSize = 1363144 (1.2999954223632812MB) MaxNewSize = 1287651328 (1228.0MB) OldSize = 5452592 (5.1999969482421875MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 1048576 (1.0MB) Heap Usage: G1 Heap: regions = 2048 capacity = 702545920 (670.0MB) used = 284513824 (271.3335266113281MB) free = 418032096 (398.6664733886719MB) 40.49754128527285% used
jcmd 17136 GC.runThen jmap one more time and we can see
Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 Heap Usage: G1 Heap: regions = 2048 capacity = 439353344 (419.0MB) used = 135954032 (129.65586853027344MB) free = 303399312 (289.34413146972656MB) 30.944121367607025% used
jinfo -flag MaxHeapFreeRatio=50 17136After that we have to again run full gc to force resizing. And now our heap looks like that:
Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 50 Heap Usage: G1 Heap: regions = 2048 capacity = 166723584 (159.0MB) used = 82849400 (79.01134490966797MB) free = 83874184 (79.98865509033203MB) 49.69266975450816% used
Now we can try going in other way:
jinfo -flag MaxHeapFreeRatio=90 17136 jinfo -flag MinHeapFreeRatio=85 17136gives jmap output
Heap Configuration: MinHeapFreeRatio = 85 MaxHeapFreeRatio = 90 Heap Usage: G1 Heap: regions = 2048 capacity = 465567744 (444.0MB) used = 69816504 (66.58220672607422MB) free = 395751240 (377.4177932739258MB) 14.995992505872572% usedResizing worked one more time and heap capacity has increased from 159MB to 444MB. We described that minimum 85% of our heap capacity should be free, and that pointed JVM to resize the heap to gain at most 15% usage. Now we're waiting for runtime XMX changing ;)
Published at DZone with permission of Jakub Kubrynski, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments