Category: GC

G1GC(Garbage First Garbage Collector) Tuning flags

Performance Metrics Several metrics are utilized to evaluate garbage collector performance, including:

  • Throughput—the percentage of total time not spent in garbage collection, considered over long periods of time.
  • Garbage collection overhead—the inverse of throughput, that is, the percentage of total time spent in garbage collection.
  • Pause time—the length of time during which application execution is stopped while garbage collection is occurring.
  • Frequency of collection—how often collection occurs, relative to application execution.
  • Footprint—a measure of size, such as heap size.
  • Promptness—the time between when an object becomes garbage and when the memory becomes available

G1 GC Glossary of Terms

Heap Region:- G1 divides the heap into heap regions. The regions for Eden, Survivor and Old are not contiguous. If -XX:G1HeapRegionSize is not defined in the command line, G1 will try to divide the heap into 2048 regions.  The selected heap region size is power of 2 MB, with the minimum of 1M, and maximum of 32M.  In other words, the heap region size is one of 1M, 2M, 4M, 8M, 16M and 32M.

Collection Set(CSet):- The set of regions to be collected in a gc pause. The number of young/survivor/old regions in CSet is decided dynamically according to pause time goal and other heuristics.

Humongous Objects:- If the size of the object is larger than ½ of the region size, then g1 treats this object as Humongous Object. Regions used for humongous objects are HS(Humongous Start) and HC(Humongous Continuous). If HS is not big enough for this object, one or multiple HC regions will be used.

Young GC:- The collection set of the young gc includes only young/survivor regions.

Mixed GC:- The collection set of the mixed gc includes both young/survivor regions, but also old regions.

Remember Set(RSet):- The RSet is like a card table for each region. It records references from other regions to objects in this region. A regions’s Remember Set consists of card addresses. These cards contain locations of references that point into this region.

JVM flag:

One word about the syntax of  XX flags. All XX flags start with “-XX:”, but then the syntax differs depending on the type of flag.

For a boolean flag, we either have a “+” or a “-” and only then the actual name of the JVM option to set. For example, -XX:+ activates the option while -XX:- deactives that option.

For a flag that takes a non-boolean value like a text string or an integer number, we first have the name of the flag followed by a “=”, and then the value to set. For example, -XX:= sets the option to the value .

The G1 GC is an adaptive garbage collector with defaults that enable it to work efficiently without modification. Here is a list of important options and their default values. This list applies to the latest Java HotSpot VM, build 24. You can adapt and tune the G1 GC to your application performance needs by entering the following options with changed settings on the JVM command line.

XX:+UseG1GC It enables the G1 GC algorithm
Threshold Flags:
-XX:G1HeapRegionSize=n Sets the size of a G1 region. The value will be a power of two and can range from 1MB to 32MB. The goal is to have around 2048 regions based on the minimum Java heap size.
-XX:MaxGCPauseMillis=200 Sets a target value for desired maximum pause time. The default value is 200 milliseconds. The specified value does not adapt to your heap size.
-XX:G1NewSizePercent=5 Sets the percentage of the heap to use as the minimum for the young generation size. The default value is 5 percent of your Java heap. This is an experimental flag. See “How to unlock experimental VM flags” for an example. This setting replaces the -XX:DefaultMinNewGenPercent setting. This setting is not available in Java HotSpot VM, build 23.
-XX:G1MaxNewSizePercent=60 Sets the percentage of the heap size to use as the maximum for young generation size. The default value is 60 percent of your Java heap. This is an experimental flag. See “How to unlock experimental VM flags” for an example. This setting replaces the -XX:DefaultMaxNewGenPercent setting. This setting is not available in Java HotSpot VM, build 23.
-XX:ParallelGCThreads=n Sets the value of the STW worker threads. Sets the value of n to the number of logical processors. The value of n is the same as the number of logical processors up to a value of 8.If there are more than eight logical processors, sets the value of n to approximately 5/8 of the logical processors. This works in most cases except for larger SPARC systems where the value of n can be approximately 5/16 of the logical processors.
-XX:-ResizePLAB Promotion Local Allocation Buffers (PLABs) are used during Young collection. Multiple threads are used.  Each thread may need to allocate space for objects being copied either in Survivor or Old space. PLABs are required to avoid competition of threads for shared data structures that manage free memory. Each GC thread has one PLAB for Survival space and one for Old space. We would like to stop resizing PLABs to avoid the large communication cost among GC threads, as well as variations during each GC.We would like to fix the number of GC threads to be the size calculated by 8+(logical processors-8)(5/8) using -XX:ParallelGCThreads=n.This formula was recently recommended by Oracle.
-XX:ConcGCThreads=n Sets the number of parallel marking threads. Sets n to approximately 1/4 of the number of parallel garbage collection threads (ParallelGCThreads).
-XX:InitiatingHeapOccupancyPercent=45 Sets the Java heap occupancy threshold that triggers a marking cycle. The default occupancy is 45 percent of the entire Java heap.
-XX:G1MixedGCLiveThresholdPercent=65 Sets the occupancy threshold for an old region to be included in a mixed garbage collection cycle. The default occupancy is 65 percent. This is an experimental flag. See “How to unlock experimental VM flags” for an example. This setting replaces the -XX:G1OldCSetRegionLiveThresholdPercent setting. This setting is not available in Java HotSpot VM, build 23.
-XX:G1HeapWastePercent=10 Sets the percentage of heap that you are willing to waste. The Java HotSpot VM does not initiate the mixed garbage collection cycle when the reclaimable percentage is less than the heap waste percentage. The default is 10 percent. This setting is not available in Java HotSpot VM, build 23.
-XX:G1MixedGCCountTarget=8 Sets the target number of mixed garbage collections after a marking cycle to collect old regions with at most G1MixedGCLIveThresholdPercent live data. The default is 8 mixed garbage collections. The goal for mixed collections is to be within this target number. This setting is not available in Java HotSpot VM, build 23.
-XX:G1OldCSetRegionThresholdPercent=10 Sets an upper limit on the number of old regions to be collected during a mixed garbage collection cycle. The default is 10 percent of the Java heap. This setting is not available in Java HotSpot VM, build 23.
-XX:G1ReservePercent=10 Sets the percentage of reserve memory to keep free so as to reduce the risk of to-space overflows. The default is 10 percent. When you increase or decrease the percentage, make sure to adjust the total Java heap by the same amount. This setting is not available in Java HotSpot VM, build 23.
-XX:SoftRefLRUPolicyMSPerMB= This defines how long the softly reachable objects will remain alive after they were referenced. The default is 1000ms per free MB in heap.
-XX:+ParallelRefProcEnabled GC uses multiple threads to process the increasing references during Young and mixed GC. With this flag for HBase, the GC remarking time is reduced by 75%, and overall GC pause time is reduced by 30%
-XX:G1ConcRefinementThreads Enables G1 concurrent refinement Threads,update RSet concurrently with the application
-XX:MaxGCPauseMillis However, this is a soft goal.  G1 will try to meet this goal, but there is no guarantee.  Especially for mixed gc.  Additional tuning is needed.
-XX:+UnlockExperimentalVMOptions  Needs to be enabled to use hidden JVM flags.
-XX:NewRatio The Young Gen size is heap size * newRatio.  NewRatio is ignored if it is used with NewSize and MaxNewSize.
-XX:G1RSetUpdatingPauseTimePercent=10 This flag sets a percent target amount (defaults to 10 percent of the pause time goal) that G1 GC should spend in updating RSets during a GC evacuation pause. You can increase or decrease the percent value, so as to spend more or less (respectively) time in updating the RSets during the stop-the-world (STW) GC pause and let the concurrent refinement threads deal with the update buffers accordingly.

Keep in mind that by decreasing the percent value, you are pushing off the work to the concurrent refinement threads; hence, you will see an increase in concurrent work.

Log garbage collection:
-XX:G1PrintRegionLivenessInfo This is a diagnostic option and gets enabled with -XX:+UnlockDiagnosticVMOptions. G1PrintRegionLivenessInfo prints the live data information of each region during the Cleanup phase of the concurrent-marking cycle
–XX:+PrintGCTimeStamps This outputs a timestamp at the start of each collection, in addition to the information that is output if the command line option –XX:+PrintGCDetails is used. The timestamps can help you correlate garbage collection logs with other logged events.
-XX:+G1PrintHeapRegions G1PrintHeapRegions option logs the regions related events when regions are committed, allocated into or are reclaimed.
-XX:+PrintAdaptiveSizePolicy Enables whether or not your application is allocating objects in humongous regions


String deduplication feature (from Java 8 update 20)

-XX:+UseStringDeduplicationJVM Since strings (and their internal char[] arrays) takes much of our heap, a new optimization has been made that enables the G1 collector to identify strings which are duplicated more than once across your heap and correct them to point into the same internal char[] array, to avoid multiple copies of the same string from residing inefficiently within the heap.
– XX:StringDeduplicationAgeThreshold=3 String deduplication is processing only strings which have survived a few garbage collections. This ensures that a majority of very short living strings will not be processed. The minimal string age is managed by this flag.JVM parameter (3 is the default value of this parameter).
-XX:+PrintStringDeduplicationStatistics To print the statistics of string de duplication.



Garbage collection flags in Java

In this post I am going give the brief summary of the GC flags and how we need to set to our Java process.

JVM Type Flag:



Heap Configuration:

-Xms<value>[k/m/g] or -XX:InitialHeapSize=<value>[k/m/g] => Initial heap size

-Xmx<value>[k/m/g] or -XX:MaxHeapSize=<value>[k/m/g]   => Maximum heap size

Ex: -Xms512m -Xmx1g

Young Generation Configuration:

It is part of heap size, value given for these flags are allocated from heap memory. Don’t configure below values until you are very sure about your environment as jvm itself takes care of allocating sizes for young generation.

Based on Size:

-XX:NewSize=<value>k/m/g  => Initial young generation size

-XX:MaxNewSize=<value>k/m/g  => Max young generation size

Ex: -XX:NewSize=100m -XX:MaxNewSize=200m

Based on Ratio:


Ex: -XX:NewRatio=3

Permanent Generation(until 1.6):

-XX:PermSize=<value>k/m/g  => Initial permgen size

-XX:MaxPermSize=<value>k/mg  => Max permgen size

Ex: -XX:PermSize=256m -XX:MaxPermSize=512m

Metaspace Configuration(1.7 onward):

-XX:MetaspaceSize=<value>k/m/g  => Initial metaspace size

-XX:MaxMetaspaceSize=<value>k/m/g  => Max metaspace size

Ex: -XX:MetaspaceSize=256m -XX:MaxMetaSpace=512m

Garbage Collection Algorithm:


Additional flags for CMS:

-XX:+CMSParallelRemarkEnabled​ => Enables CMS

-XX:+UseParNewGC  => Enables CMS for young generation, need not to set this explicitly, it is enabled automatically when CMS is enabled

-XX:+CMSClassUnloadingEnabled  => Enables GC at young generation

-XX:+ScavengeBeforeFullGC  => Instructs jvm to do gc on young generation before full gc

-XX:+CMSScavengeBeforeRemark  => Instructs jvm to do gc on young generation before remark phase in cms

-XX:CMSInitiatingOccupancyFraction=<percentage>  => Heap percentage to invoke gc

-XX:+UseCMSInitiatingOccupancyOnly   => Instructs jvm to do gc always when heap reached fraction perdentage

CMS Thread Configuration: Configure this after understanding the system very well.


Ex: -XX:ConcGCThreads=2

GC Logs Configuration:

-verbose:gc  => Enables GC logs

-XX:+PrintGCDetails => Enables more gc logs

-XX:+PrintGCDateStamps  => Prints human readable date time format in gc logs

-XX:+PrintTenuringDistribution => Prints the tenuring distribution for objects(Not advisable for production)

-Xloggc:<gc log file location> => GC Log file location

-XX:+UseGCLogFileRotation  => Enables gc log rotation

-XX:GCLogFileSize=<gc log file size>[k/m/g]  => Log file size

-XX:NumberOfGCLogFiles=<Log file backup index> => Log files backup index, maximum number of files 

Disable Explicit GC:

-XX:+DisableExplicitGC => Disabled explicit gc


-XX:+ExplicitGCInvokesConcurrent  => Enables explicit GC but CMS is invoked when GC getting called explicitly


-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses  => Enables explicit GC but CMS with Young generation GC is invoked when GC getting called explicitly

Heap Dump When Out Of Memory:

We can instruct jvm to create heap dump when out of memory occurs. Heap dump is huge in size so it always good to give the path for heap dump where enough space is available. This heap dump will help us to understand the reason for outofmemory.



Final Configuration:

After adding all the above discussed parameter our JVM configuration will looks like,

-server -Xms2g -Xmx2g -XX:MaxNewSize=512m -XX:MaxMetaspaceSize=512m -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintTenuringDistribution -Xloggc:/var/gc_logs/tomcat_gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=25M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/heap_dump -XX:+DisableExplicitGC