In this article I have collected a list of options related to GC tuning in JVM. This is not a comprehensive list, I have only collected options which I use in practice (or at least understand why I may want to use them).
HotSpot GC collectors
HotSpot JVM may use one of 6 combinations of garbage collection algorithms listed below.
Young collector  |    Old collector  |    JVM option  |   
Serial   (DefNew)  |    Serial   Mark-Sweep-Compact  |    -XX:+UseSerialGC  |   
Parallel   scavenge (PSYoungGen)  |    Serial Mark-Sweep-Compact   (PSOldGen)  |    -XX:+UseParallelGC  |   
Parallel   scavenge (PSYoungGen)  |    Parallel Mark-Sweep-Compact   (ParOldGen)  |    -XX:+UseParallelOldGC  |   
Serial   (DefNew)  |    Concurrent   Mark Sweep  |    -XX:+UseConcMarkSweepGC    -XX:-UseParNewGC  |   
Parallel   (ParNew)  |    Concurrent   Mark Sweep  |    -XX:+UseConcMarkSweepGC    -XX:+UseParNewGC  |   
G1  |    -XX:+UseG1GC  |   |
GC logging options
JVM option  |    Description  |   
General options  |   |
-verbose:gc or -XX:+PrintGC  |    Print basic GC info  |   
-XX:+PrintGCDetails  |    Print more elaborated GC info  |   
-XX:+PrintGCTimeStamps  |    Print timestamps for each GC event (seconds count from start of JVM)  |   
-Xloggc:<file>  |    Redirects GC output to file instead of console  |   
-XX:+PrintTenuringDistribution  |    Print detailed demography of young space after each collection   |   
-XX:+PrintTLAB  |    Print TLAB allocation statistics  |   
-XX:+PrintGCApplication\ StoppedTime  |    Print pause summary after each stop-the-world pause  |   
-XX:+PrintGCApplication\ ConcurrentTime  |    Print time for each concurrent phase of GC   |   
-XX:+HeapDumpAfterFullGC  |    Creates heap dump file after full GC  |   
-XX:+HeapDumpBeforeFullGC  |    Creates heap dump file before full GC   |   
-XX:+HeapDumpOnOutOfMemoryError  |    Creates heap dump in out-of-memory condition  |   
-XX:HeapDumpPath=<path>  |    Specifies path to save heap dumps  |   
CMS specific options  |   |
-XX:PrintCMSStatistics=<n>  |    Print additional CMS statistics if n >= 1  |   
-XX:+PrintCMSInitiationStatistics  |    Print CMS initiation details  |   
-XX:PrintFLSStatistics=2  |    Print additional info concerning free lists  |   
-XX:PrintFLSCensus=2  |    Print additional info concerning free lists  |   
-XX:+CMSDumpAtPromotionFailure  |    Dump useful information about the state of the CMS   old generation upon a promotion failure.  |   
-XX:+CMSPrintChunksInDump  |    In a CMS dump enabled by option above, include more detailed information about the free chunks.  |   
-XX:+CMSPrintObjectsInDump  |    In a CMS dump enabled by option above, include more detailed information about the allocated   objects.  |   
JVM sizing options
JVM option  |    Description  |   
-Xms<size> -Xmx<size>  or ‑XX:InitialHeapSize=<size>  ‑XX:MaxHeapSize=<size>  |    Initial and max size of heap space (young space +   tenured space). Permanent space does not count to this size.  |   
-XX:NewSize=<size>  -XX:MaxNewSize=<size>  |    Initial and max size of young space.  |   
-XX:NewRatio=<ratio>  |    Alternative way to specify young space size. Sets   ration of young vs tenured space (e.g. -XX:NewRatio=2 means that young space   will be 2 time smaller than tenuted space).  |   
-XX:SurvivorRatio=<ratio>  |    Sets size of single survivor space as a portion of Eden space size   (e.g. -XX:NewSize=64m -XX:SurvivorRatio=6 means that each survivor space will   be 8m and eden will be 48m).  |   
-XX:PermSize=<size>  -XX:MaxPermSize=<size>  |    Initial and max size of permanent space.  |   
-Xss=<size>   or -XX:ThreadStackSize=<size>  |    Sets size of stack area dedicated to each thread. Thread stacks do   not count to heap size.  |   
-XX:MaxDirectMemorySize=<value>  |    Maximum size of off-heap memory available for JVM  |   
Young collection tuning
JVM option  |    Description  |   
-XX:InitialTenuringThreshold=<n>  |    Initial value for tenuring threshold (number of   collections before object will be promoted to tenured space).  |   
-XX:MaxTenuringThreshold=<n>  |    Max value for tenuring threshold.  |   
-XX:PretenureSizeThreshold=<size>  |    Max object size allowed to be allocated in young   space (large objects will be allocated directly in old space). Thread local   allocation bypasses this check so if TLAB is large enough object exciding   size threshold still may be allocated in young.  |   
-XX:+AlwaysTenure  |    Promote all objects surviving young collection immediately to tenured   space (equivalent of -XX:MaxTenuringThreshold=0)  |   
-XX:+NeverTenure  |    Objects from young space will never get promoted to   tenured space while survivor space is large enough to keep them.  |   
Thread local allocation blocks  |   |
-XX:+UseTLAB  |    Use thread local allocation blocks in young space.   Enabled by default.  |   
-XX:+ResizeTLAB  |    Allow JVM to adaptively resize TLAB for threads.  |   
-XX:TLABSize=<size>  |    Initial size of TLAB for thread  |   
-XX:MinTLABSize=<size>  |    Minimal allowed size of TLAB  |   
CMS tuning options
JVM option  |    Description  |   
Controlling initial mark phase  |   |
-XX:+UseCMSInitiatingOccupancyOnly  |    Only use occupancy as a criterion for starting a CMS collection.  |   
-XX:CMSInitiating\ OccupancyFraction=<n>  |    Percentage CMS generation occupancy to start a CMS   collection cycle. A negative value means that CMSTriggerRatio is used.  |   
-XX:CMSBootstrapOccupancy=<n>  |    Percentage CMS generation occupancy at which to initiate CMS   collection for bootstrapping collection stats.  |   
-XX:CMSTriggerRatio=<n>  |    Percentage of MinHeapFreeRatio in CMS generation   that is allocated before a CMS collection cycle commences.  |   
-XX:CMSTriggerPermRatio=<n>  |    Percentage of MinHeapFreeRatio in the CMS perm generation that is   allocated before a CMS collection cycle commences, that also collects the   perm generation.  |   
-XX:CMSWaitDuration=<timeout>  |    Once CMS collection is triggered, it will wait for   next young collection to perform initial mark right after. This parameter specifies   how long CMS can wait for young collection.  |   
Controlling remark phase  |   |
-XX:+CMSScavengeBeforeRemark  |    Force young collection before remark phase.  |   
-XX:+CMSScheduleRemark\ EdenSizeThreshold  |    If Eden used is below this value, don't try to schedule remark  |   
-XX:CMSScheduleRemark\ EdenPenetration=<n>  |    The Eden occupancy % at which to try and schedule   remark pause  |   
-XX:CMSScheduleRemark\ SamplingRatio=<n>  |    Start sampling Eden top at least before young generation occupancy   reaches 1/  |   
Parallel execution  |   |
-XX:+UseParNewGC  |    Use parallel algorithm for young space collection.  |   
-XX:+CMSConcurrentMTEnabled  |    Use multiple threads for concurrent phases.  |   
-XX:ConcGCThreads=<n>  |    Number of parallel threads used for concurrent phase.  |   
-XX:+ParallelGCThreads=<n>  |    Number of parallel threads used for stop-the-world   phases.  |   
CMS incremental mode  |   |
-XX:+CMSIncrementalMode  |    Enable incremental CMS mode. Incremental mode is   meant for severs with small number of CPU.  |   
Miscellaneous options   |   |
-XX:+CMSClassUnloadingEnabled  |    If not enabled, CMS will not clean permanent space. You   should always enable it in multiple class loader environments such as JEE or   OSGi.  |   
-XX:+ExplicitGCInvokesConcurrent  |    Let System.gc() trigger concurrent collection instead of full GC.  |   
‑XX:+ExplicitGCInvokesConcurrent\ AndUnloadsClasses  |    Same as above but also triggers permanent space   collection.  |   
Miscellaneous GC options
JVM option  |    Description  |   
-XX:+DisableExplicitGC  |    JVM will ignore application calls to System.gc()  |   

Parallel (ParNew) Concurrent Mark Sweep
ReplyDeleteShould be:
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
Indeed.
ReplyDeleteThank you.
Good collection man. GC tuning is a hard thing to achieve and require patience and profiling but indeed knowledge of these JVM options helps to understand the behavior.
ReplyDeleteJavin
What is garbage collection in Java
Hi
ReplyDeleteI have a question. What jvm parameter I have to use to force the full garbage collection?
Greetings
I would suggest you add -XX:+PrintGCDateStamps which will prefix the wall clock time which is very helpfull to correlate GC events with Business incidents.
ReplyDeleteBTW: some blogs report one can add the Date and remove the seconds, but in my tests -PrintGCTimeStamps seems not to help. (it is possible to remove them in the HotSpotsDiagnostics MBean).
Actually -PrintGCTimeStamp works, if you speficy is after Xloggc. --eckes
DeleteMissing -XX:+PrintReferenceGC
ReplyDelete