Organizing garbage collectors in HotSpot, IBM J9, JRockit JVMs
This article is intended to systematize knowledge of all modern garbage collectors used in HotSpot, JRockit, and J9 JVMs. This article provides a brief overview of all garbage collection modes with similarities between all the JVMs discussed here. The article will be interesting to everyone who is interested in the GC issue, and will also be useful to those who are considering or planning to port JAVA applications to alternative JVMs.
It is assumed that the reader is already familiar with the basic concepts of garbage collection - such as the Copying collector, Mark-Sweep-Compact algorithm, and generational garbage collection (Generational collection).
It should also be said right away that the article does not claim to be a complete exposition of garbage collection algorithms; the network has fairly well-illustrated materials on any of the algorithms. Implementations of conceptually similar algorithms can differ greatly from one JVM to another - if the single-threaded Mark-Sweep-Compact is everywhere implemented approximately the same, then the competitive Mark-Sweep-Compact already has various variations, which are also not affected here.
Almost all garbage collection modes in HotSpot use generation by generation. The entire Heap is divided into 3 generations depending on the age of the objects - respectively Young for young, Tenured for "mature" and Perm for classes and constant pools. In turn, the Young generation is divided into 3 more areas - Eden and 2 Surviver areas. First, objects are created in Eden, then they fall into the Surviver area (one or more times), and then only in Tenured. For G1, generational division also exists, but has a different character (described below).
Copy (-XX: + UseSerialGC) A
single- stream ( serial ) copy collector for the Young generation.
ParNew (-XX: + UseParNewGC) A multi-
threaded ( parallel ) copy collector for the Young generation.
MarkSweepCompact (-XX: + UseSerialGC)
Single-threaded collector for Tenured generation using Mark-Sweep-Compact algorithm.
ConcurrentMarkSweep (-XX: + UseConcMarkSweepGC)
Competitive Mark-Sweep ( concurrent ) collector for Tenured generation, most of the time working simultaneously with application threads. With strong fragmentation, MarkSweepCompact turns to single-threaded for help . Additional options are possible:
PS Scavenge + PS MarkSweep (-XX: + UseParallelGC -XX: + UseParallelOldGC)
For the Young generation, a multi-threaded PS Scavenge copy collector similar to ParNew is used . For the Tenured generation, PS MarkSweep is used - a multi-threaded version of the Mark-Sweep-Compact algorithm. This pair of collectors supports the so-called. Adaptive Size Policy (or GC ergonomics) - JVM's ability to automatically optimize the sizes of Young and Tenured generations to achieve specified pauses. Additional options are possible:
G1 Young Generation + G1 Mixed Generation (-XX: + UseG1GC)
A new mode using a "regional" build. Heap is divided into many regions of equal size (0.5-2 mb). A competitive tracing-marking process estimates the size of living objects in the regions, this happens in parallel without stopping application flows. In the next cycle, GC processes all Young regions (special regions in which new objects are created), as well as several those in which the smallest size of living objects. T.O. the collector minimizes the number of copies between regions. Here you can also set the desired pause time:
Unlike HotSpot, in J9 only one mode uses build over generations. However, in this case, the Young generation is divided not into 3, but into 2 areas - Eden and Surviver. T.O. an object from Surviver will immediately go to Tenured. And if Eden <Surviver, then some objects immediately have a chance to get from Eden to Tenured.
-Xgcpolicy: optthruput
Multi-threaded Mark-Sweep-Compact collector that processes the entire Heap.
-Xgcpolicy: optavgpause
Competitive Mark-Sweep-Compact collector for the entire Heap, most of the time working simultaneously with the application. Designed to smooth out pauses caused by GC.
-Xgcpolicy: gencon
Generator for generations. For the younger generation, a multi-threaded copy collector is used, but instead of 3 areas, only 2 are used - Eden and Surviver. Objects caught in Surviver in the next GC cycle will fall into the Tenured generation. For the Tenured generation, the competitive Mark-Sweep-Compact manifold described above is used.
-Xgcpolicy: balanced
A new collector using Heap division into many regions. Similar in concept to G1 in Oracle HotSpot.
JRockit 2 builds by generation, but the Young generation is even simpler - it does not break at all, and at the first collector cycle, objects from Eden immediately fall into Tenured.
JRockit allows you to choose between dynamic and static modes. Dynamic modes - throughput, pausetime, deterministic - determine the goal, and can dynamically change the parameters and the assembly algorithm itself, depending on the situation. There are also static modes that more accurately determine how garbage can be collected, and we will stop on them:
-Xgc: singlepar A multi-
threaded Mark-Sweep-Compact collector that processes the entire Heap.
-Xgc: genpar
Generator for generations. For the young generation, a multi-threaded copy collector is used. For the Tenured generation, the multi-threaded Mark-Sweep-Compact is used.
-Xgc: singlecon
Competitive Mark-Sweep-Compact collector for the entire Heap, most of the time working simultaneously with the application.
-Xgc: gencon Generator
for generations. For the young generation, a single-threaded copy collector is used. For the Tenured generation, a competitive Mark-Sweep-Compact collector similar to singlecon is used .
In HotSpot JVM, it is possible to individually set the type of collector for each generation. However, not every Young generation collector can work with any of the Tenured generation collectors. There are only 6 possible combinations. All of them are listed in the table below with the corresponding (if any) analogies in JRockit and J9.
* - The similarity is only in the method of cleaning Tenured generation.
http://www.fasterj.com/articles/oraclecollectors1.shtml
http://www.ibm.com/developerworks/websphere/techjournal/1106_bailey/1106_bailey.html
http://www.ibm.com/developerworks/websphere/ techjournal / 1108_sciampacone / 1108_sciampacone.html
http://www.techpaste.com/2012/02/java-garbage-collectors-gc/
http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnosos /memman.html#wp1087125
http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html#wp1017849
It is assumed that the reader is already familiar with the basic concepts of garbage collection - such as the Copying collector, Mark-Sweep-Compact algorithm, and generational garbage collection (Generational collection).
It should also be said right away that the article does not claim to be a complete exposition of garbage collection algorithms; the network has fairly well-illustrated materials on any of the algorithms. Implementations of conceptually similar algorithms can differ greatly from one JVM to another - if the single-threaded Mark-Sweep-Compact is everywhere implemented approximately the same, then the competitive Mark-Sweep-Compact already has various variations, which are also not affected here.
Oracle HostSpot JVM (Versions 6 and 7)
Almost all garbage collection modes in HotSpot use generation by generation. The entire Heap is divided into 3 generations depending on the age of the objects - respectively Young for young, Tenured for "mature" and Perm for classes and constant pools. In turn, the Young generation is divided into 3 more areas - Eden and 2 Surviver areas. First, objects are created in Eden, then they fall into the Surviver area (one or more times), and then only in Tenured. For G1, generational division also exists, but has a different character (described below).
Copy (-XX: + UseSerialGC) A
single- stream ( serial ) copy collector for the Young generation.
ParNew (-XX: + UseParNewGC) A multi-
threaded ( parallel ) copy collector for the Young generation.
MarkSweepCompact (-XX: + UseSerialGC)
Single-threaded collector for Tenured generation using Mark-Sweep-Compact algorithm.
ConcurrentMarkSweep (-XX: + UseConcMarkSweepGC)
Competitive Mark-Sweep ( concurrent ) collector for Tenured generation, most of the time working simultaneously with application threads. With strong fragmentation, MarkSweepCompact turns to single-threaded for help . Additional options are possible:
- -XX: ± CMSIncrementalMode - uses or disables an incremental concurrent GC algorithm
- -XX: ± CMSConcurrentMTEnabled - uses or disables parallel (multiple threads) concurrent GC algorithm
- -XX: ± UseCMSCompactAtFullCollection - uses or disables a compaction when a full GC occurs
PS Scavenge + PS MarkSweep (-XX: + UseParallelGC -XX: + UseParallelOldGC)
For the Young generation, a multi-threaded PS Scavenge copy collector similar to ParNew is used . For the Tenured generation, PS MarkSweep is used - a multi-threaded version of the Mark-Sweep-Compact algorithm. This pair of collectors supports the so-called. Adaptive Size Policy (or GC ergonomics) - JVM's ability to automatically optimize the sizes of Young and Tenured generations to achieve specified pauses. Additional options are possible:
- -XX: ± UseAdaptiveSizePolicy - uses or disables Adaptive Size Policy
- -XX: MaxGCPauseMillis = nnn - sets desirable max GC pause time
- -XX: GCTimeRatio = nnn - sets desirable relation between application and GC work times
G1 Young Generation + G1 Mixed Generation (-XX: + UseG1GC)
A new mode using a "regional" build. Heap is divided into many regions of equal size (0.5-2 mb). A competitive tracing-marking process estimates the size of living objects in the regions, this happens in parallel without stopping application flows. In the next cycle, GC processes all Young regions (special regions in which new objects are created), as well as several those in which the smallest size of living objects. T.O. the collector minimizes the number of copies between regions. Here you can also set the desired pause time:
- -XX: MaxGCPauseMillis = nnn - sets desirable max GC pause time
IBM J9 JVM
Unlike HotSpot, in J9 only one mode uses build over generations. However, in this case, the Young generation is divided not into 3, but into 2 areas - Eden and Surviver. T.O. an object from Surviver will immediately go to Tenured. And if Eden <Surviver, then some objects immediately have a chance to get from Eden to Tenured.
-Xgcpolicy: optthruput
Multi-threaded Mark-Sweep-Compact collector that processes the entire Heap.
-Xgcpolicy: optavgpause
Competitive Mark-Sweep-Compact collector for the entire Heap, most of the time working simultaneously with the application. Designed to smooth out pauses caused by GC.
-Xgcpolicy: gencon
Generator for generations. For the younger generation, a multi-threaded copy collector is used, but instead of 3 areas, only 2 are used - Eden and Surviver. Objects caught in Surviver in the next GC cycle will fall into the Tenured generation. For the Tenured generation, the competitive Mark-Sweep-Compact manifold described above is used.
-Xgcpolicy: balanced
A new collector using Heap division into many regions. Similar in concept to G1 in Oracle HotSpot.
Oracle JRockit JVM
JRockit 2 builds by generation, but the Young generation is even simpler - it does not break at all, and at the first collector cycle, objects from Eden immediately fall into Tenured.
JRockit allows you to choose between dynamic and static modes. Dynamic modes - throughput, pausetime, deterministic - determine the goal, and can dynamically change the parameters and the assembly algorithm itself, depending on the situation. There are also static modes that more accurately determine how garbage can be collected, and we will stop on them:
-Xgc: singlepar A multi-
threaded Mark-Sweep-Compact collector that processes the entire Heap.
-Xgc: genpar
Generator for generations. For the young generation, a multi-threaded copy collector is used. For the Tenured generation, the multi-threaded Mark-Sweep-Compact is used.
-Xgc: singlecon
Competitive Mark-Sweep-Compact collector for the entire Heap, most of the time working simultaneously with the application.
-Xgc: gencon Generator
for generations. For the young generation, a single-threaded copy collector is used. For the Tenured generation, a competitive Mark-Sweep-Compact collector similar to singlecon is used .
Concordance table of various garbage collection modes
In HotSpot JVM, it is possible to individually set the type of collector for each generation. However, not every Young generation collector can work with any of the Tenured generation collectors. There are only 6 possible combinations. All of them are listed in the table below with the corresponding (if any) analogies in JRockit and J9.
Oracle HotSpot | Ibm j9 | Oracle JRockit |
---|---|---|
-XX: + UseSerialGC Copy + MarkSweepCompact | ||
-XX: + UseG1GC G1 Young + G1 Mixed | -Xgcpolicy: balanced | |
-XX: + UseParallelGC -XX: + UseParallelOldGC PS Scavenge + PS MarkSweep | -Xgcpolicy: optthruput * | -Xgc: genpar -Xgc: singlepar * |
-XX: + UseParNewGC ParNew + MarkSweepCompact | ||
-XX: + UseConcMarkSweepGC -XX: + UseParNewGC ParNew + ConcurrentMarkSweep | -Xgcpolicy: optavgpause * | -Xgc: singlecon * |
-XX: + UseConcMarkSweepGC -XX: -UseParNewGC Copy + ConcurrentMarkSweep | -Xgcpolicy: gencon -Xgcpolicy: optavgpause * | -Xgc: gencon -Xgc: singlecon * |
* - The similarity is only in the method of cleaning Tenured generation.
Sources
http://www.fasterj.com/articles/oraclecollectors1.shtml
http://www.ibm.com/developerworks/websphere/techjournal/1106_bailey/1106_bailey.html
http://www.ibm.com/developerworks/websphere/ techjournal / 1108_sciampacone / 1108_sciampacone.html
http://www.techpaste.com/2012/02/java-garbage-collectors-gc/
http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnosos /memman.html#wp1087125
http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html#wp1017849