Make writing a habit together! This is the 11th day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

Before I talk about garbage collectors, I need to know what garbage collection algorithms are common in the JVM, as described in this blog post. If collection algorithms are the methodology of memory collection, the garbage collector is the practice of memory collection. The following is a detailed review of the Serial, ParNew, Parallel Scavenge, Serial Old, Parallel Old, CMS, G1 garbage collector and their application scenarios.

The basic concept

Different GC’s represent different meanings

Partial GC: Indicates that the entire GC heap is not collected.

  • Young GC: Only GC of the Young generation is collected.
  • Old GC: Only Old GC is collected.
  • Mixed GC: Collects GCS for the entire young generation and some of the old generation. This is specific to the G1 collector.

Full GC: Collects the entire heap, including all parts of the young generation, old generation, permanent generation (if any), and so on.

Throughput

Throughput is the ratio of CPU time spent running user code to total CPU consumption, i.e. Throughput = user code time run/(user code time run + garbage collection time).

Assuming a total of 100 minutes of virtual machine running and 1 minute of garbage collection, the throughput is 99%.

Generally speaking, shorter pause times (low latency) are more suitable for applications that need to interact with users or ensure quality of service response. Good response speed improves user experience;

The high throughput can make the most efficient use of processor resources and complete the operation tasks of the program as soon as possible, which is mainly suitable for the analysis tasks without too much interaction in the background.

The concept of “concurrency” and “parallelism” in garbage collectors

Parallelism and concurrency are technical terms in concurrent programming, and in the context of talking about garbage collectors, they can be understood as:

  • Parallel: Parallel describes the relationship between multiple garbage collector threads, indicating that more than one such thread is working together at the same time. By default, the user thread is in a waiting state.
  • Concurrent: Concurrency describes the relationship between garbage collector and user threads, indicating that both garbage collector and user threads are running at the same time. Since the user thread is not frozen, the program can still respond to service requests, but the throughput of the application’s processing is affected because the garbage collector thread occupies a portion of the system resources.

Garbage collector

Serial collector

Features:

  • The default Cenozoic collector in client mode
  • Single-threaded work (its “single-threaded” meaning does not merely mean that it will only use one processor or one collection thread for garbage collection, but more importantly, it must suspend all other worker threads while garbage collection is in progress until the collection is complete)
  • Simple and efficient (compared to the single-threaded of other collectors)
  • For memory-constrained environments, it is the smallest Memory Footprint of any collector
  • For single-core processors or environments with a small number of processor cores, the Serial collector can achieve maximum single-thread collection efficiency by focusing on garbage collection because there is no overhead of thread interaction

The Serial/Serial Old collector works together as follows:

ParNew collector

Features:

  • The multithreaded parallel version of The Serial collector (with The exception of using multiple threads simultaneously for garbage collection, The behavior (including all The control parameters available to The Serial collector, collection algorithms, Stop The World, object allocation rules, collection policies, and so on) is exactly The same as The Serial collector, The two collectors also share quite a bit of code in their implementation.)
  • The preferred Cenozoic collector in server mode prior to JDK 7 (an important reason: It is currently the only one that works with the CMS collector besides the Serial collector)
  • The ParNew collector is used after the CMS is activated-XX: +UseConcMarkSweepGCThe default Cenozoic collector can also be used-XX: +/-UseParNewGCOption to force or disable it.
  • The ParNew collector will never perform better than the Serial collector in a single-core processor environment
  • By default, the number of collection threads enabled is the same as the number of processor cores-XX: ParallelGCThreadsParameter to limit the number of garbage collection threads)

The ParNew/Serial Old collector works together as follows:

Parallel avenge

Features:

  • Cenozoic collector
  • Based on mark-copy algorithm
  • Multithreaded collector
  • The Parallel Avenge collector is different from the CMS insane, which focuses on minimizing the downtime of user threads during garbage collection. The Parallel Avenge collector aims to achieve a controlled throughput.
  • Adaptive adjustment strategy (through+UseAdaptiveSizePolicyParameter activation)

Parameters:

  • - XX: MaxGCPauseMillisParameters: The allowed value is a number of milliseconds greater than 0, and the collector will do its best to ensure that memory reclamation takes no longer than the user set value.
  • - XX: GCTimeRatioParameter: an integer greater than 0 and less than 100, which is the ratio of garbage collection time to total time, equivalent to the reciprocal of throughput. For example, if this parameter is set to 19, the maximum allowed garbage collection time is 5% of the total time (i.e. 1/(1+19)). The default is 99, which is the maximum allowed garbage collection time of 1% (i.e. 1/(1+99)).
  • +UseAdaptiveSizePolicyParameter: This is a switch parameter. When this parameter is enabled, there is no need to manually specify the size of the new generation (-xMN), Eden to Survivor ratio (-xx: SurvivorRatio), and size of the promoted old age object (-xx: SurvivorRatio). PretenureSizeThreshold), the VM collects performance monitoring information based on the current system,Dynamic adjustmentThese parameters provide the most appropriate pause times or maximum throughput. Just set the basic memory data (such as -xmx maximum heap) and use it- XX: MaxGCPauseMillisParameter (more focused on maximum pause time) or- XX: GCTimeRatioThe (more throughput focused) parameter sets an optimization goal for the virtual machine, and the virtual machine does the fine-tuning of the details.

Serial Old collector

Features:

  • An older version of the Serial collector
  • Single-threaded collector
  • Use a mark-de-clutter algorithm
  • It is mainly used in client mode. If in server mode, it may also serve two purposes: The Application is used in JDK 5 and earlier with the Parallel Scavenge collector, and the application is used as a fallback in the event of a Concurrent Mode Failure in a Concurrent collection.

The Serial/Serial Old collector works together as follows:

Parallel Old Collector (released in JDK 6)

Features:

  • An older version of the Parallel Exploiter
  • Multithreaded concurrent collection
  • Use a mark-de-clutter algorithm
  • The Parallel Avenge plus Parallel Old collector is a priority for applications where throughput is important or where processor resources are scarce.

The Parallel Avenge /Parallel Old collector is illustrated as follows:

CMS collector (released in JDK 5)

Features:

  • The old collector
  • Use a mark-clear algorithm
  • The first truly concurrent garbage collector was the first to allow garbage collection threads to work (basically) at the same time as user threads (concurrent collection)
  • Collector that aims to obtain the shortest collection pause time (low pause)
  • It is often used as the server of Internet websites or browser-based B/S systems (such applications usually pay more attention to the response speed of services and hope that the system pause time is as short as possible to bring users a good interactive experience).

Collection process:

The four steps in The whole CMS process are as follows, among which initial marking and re-marking are still required to “Stop The World”.

  1. Initial tag – just tag objects that GC Roots can be directly associated with, very fast
  2. Concurrent tagging – The process of traversing the entire object graph from the directly associated object of GC Roots, which is time-consuming but does not require the user thread to be paused and can be run concurrently with the garbage collection thread
  3. Relabelling – To correct the marking record of the part of the object whose mark changed as the user program continued to operate during concurrent marking, the pause time in this phase is usually slightly longer than in the initial marking phase, but much shorter than in the concurrent marking phase
  4. Concurrent cleanup – Cleanup removes dead objects as judged by the marking phase. Since there is no need to move live objects, this phase can also be concurrent with the user thread

The Concurrent Mark Sweep collector runs as follows:

Disadvantages:

  • The CMS collector is very sensitive to processor resources. In fact, programs designed for concurrency are sensitive to processor resources. In the concurrent phase, it does not cause user threads to pause, but it does slow down the application and reduce overall throughput by taking up a portion of the threads.
  • Because The CMS collector is unable to handle “floating garbage,” it is possible for a “con-current Mode Failure” to occur, resulting in another Full “Stop The World” GC.
  • CMS is a collector based on “tag – clear” algorithm, which means that when it has a lot of space debris, collected over space debris too much, will bring a lot of trouble to the large object allocation, often appear old age still has a lot of the remaining space, but is unable to find a large enough contiguous space to allocate the object, When you have to trigger a Full GC early.

CMS collector floating garbage note:

Due to concurrent tags in CMS and concurrent cleanup phase, user thread is continues to run, the program is running will also naturally accompanied by a new garbage objects are generated, but this is part of the garbage objects appear in the marking process after the CMS cannot be in when to collect to get rid of them, so we have to leave to clean up again when the next garbage collection. This part of garbage is called “floating garbage”.

Because the user thread in garbage collection phase needs to be run continuously, then you also need to set aside enough memory space for user thread is used, therefore the CMS collector can’t wait to old s almost like other collector is completely filled to be collected, must set aside part of space for the use of the concurrent collection program operation.

G1 collector (Garbage First)

Features:

  • By “dividing heap memory into parts”, the collector design idea oriented to local collection and region-based memory layout was initiated
  • Full-heap-oriented collectors no longer require the cooperation of other next-generation collectors
  • A garbage collector that is primarily oriented toward server applications
  • G1 is still designed with generational collection in mind, but its heap memory layout is very different from other collectors
  • G1 no longer insists on a fixed size and a fixed number of generational regions, but divides the continuous Java heap into multiple independent regions of equal size. Each Region can act as the Eden space, Survivor space or old chronspace of the new generation according to needs
  • The collector can apply different strategies to regions that play different roles, so that both newly created objects and old objects that have survived multiple collections for a while can be collected well
  • Regions also have a special class of Humongous regions that are used to store large objects.G1 considers large objects as long as the size of a Region exceeds half of its capacity.The size of each Region can be determined by parameters- XX: G1HeapRegionSizeThe value ranges from 1MB to 32MB, and is the NTH power of 2. However, super-large objects that exceed the capacity of the entire Region will be stored in N consecutive Humongous regions. Most of G1 behaviors treat Humongous regions as part of the old era
  • The G1 collector is able to model predictable pause times because it uses regions as the smallest unit of a single collection, that is, each collection of memory is an integer multiple of Region size, so that it can systematically avoid all-region garbage collection across the entire Java heap
  • The G1 collector tracks the “value” of garbage accumulation in each Region, which is the amount of space collected and the experience of how long it takes to collect, and then maintains a list of priorities in the background, each time using a user-specified collection pause (using parameters)- XX: MaxGCPauseMillisSpecify, default is 200 milliseconds), and prioritize regions with the greatest return on value
  • Can be specified by the user expectations pause time is a very powerful a G1 collector, set different expectations pauses, the G1 may be obtained in different application scenarios focuses on throughput and delay the best balance between (the default pause targets for two hundred milliseconds, usually set expectations pauses to controlled milliseconds or hundred milliseconds would be reasonable)

G1 collector Region partition diagram is as follows:

The main steps of G1 collector operation are as follows:

  • Initial tag: Just mark the objects that GC Roots can associate directly with, and change the value of the TAMS pointer so that the next phase of user threads running concurrently will allocate new objects correctly in the available regions. This phase requires the thread to pause, but it is very short, and it is done synchronously during the Minor GC, so the G1 collector actually has no additional pauses during this phase.
  • Concurrent marking: Reachability analysis of objects in the heap is performed starting with GC Root, recursively scanning the entire heap object graph for objects to reclaim. This phase is time-consuming, but can be performed concurrently with user programs. When the object graph scan is complete, it is also necessary to reprocess the objects recorded by SATB that have reference changes at the time of concurrency.
  • Final mark: Another short pause is made on the user thread to deal with the last few SATB records that remain after the end of the concurrent phase.
  • Filter recycling: You can update the statistics of a Region, sort the reclamation value and cost of each Region, and make a reclamation plan based on the pause time expected by users. You can select multiple regions to form a collection and copy the surviving objects of the Region to an empty Region. Then clean up the entire old Region. The operation here involves the movement of the living object, which must suspend the user thread, and is done in parallel by multiple collector threads.

As you can see from the description of the phases above, the G1 collector is also intended to completely suspend user threads in addition to concurrent markers. In other words, it is not a pure pursuit of low latency; its official goal is to achieve the highest throughput possible with manageable latency.

The G1 collector runs as follows:

Similarities and differences between the G1 collector and CMS collector

  • Both are very focused on pause time control
  • G1 can specify the maximum pause time, memory layout by Region, and dynamically determine collection by revenue
  • Unlike CMS’s mark-clean algorithm, G1 is a collector based on the mark-clean algorithm as a whole, but it is also based on the mark-copy algorithm locally (between two regions). Either way, both algorithms mean that G1 does not generate memory fragmentation during operation. Provides neat free memory after garbage collection is complete. This feature makes it easier for programs to run for long periods of time and not to trigger the next collection prematurely if they cannot find contiguous memory space when allocating memory for large objects
  • Both G1 and CMS use card tables to handle cross-generation Pointers, but G1’s card table implementation is more complex, and each Region in the heap, whether playing a new or old role, must have a card table, resulting in G1’s memory set (and other memory consumption) potentially accounting for 20% or more of the total heap capacity. The CMS card table is quite simple, there is only one, only need to deal with the old to the new generation of references, not the other way around
  • They both use write barriers, which CMS uses to update and maintain card tables; In addition to using post-write barriers for the same (and more cumbersome) card table maintenance operations in G1, pre-write barriers are also used to track pointer changes during concurrency in order to implement the raw snapshot search (SATB) algorithm. Compared to the incremental update algorithm, the raw snapshot search can reduce the cost of concurrent tagging and relabeling phases and avoid the CMS disadvantage of long pause times in the final tagging phase, but it does incur the additional burden of tracking reference changes as the user program runs.

Usually when we say which collector is better, and how much better, it is usually a quantitative comparison for a specific scenario. According to practical experience, CMS is still more likely to perform better than G1 in small-memory applications, while G1 can give full play to its advantages in large-memory applications. The balance point of Java heap capacity between 6GB and 8GB is usually reached. Of course, this is just a rule of thumb, and different applications need to be tested individually to get the best results.

How are garbage collectors used together?

If there is a line between two collectors, they can be used together, and the region of the collector in the figure indicates whether it belongs to a new generation or an old generation.

Since JDK 9, the combination of ParNew plus CMS collector is not officially recommended as a collector solution in server-side mode. It was expected to be completely replaced by G1, and the support for the combination of ParNew plus Serial Old and Serial plus CMS was also removed. At this point, ParNew and CMS can only be used with each other.

Description of common garbage collector parameters

  • UseSerialGC: the default value in client mode. The Serial+Serial old collector is used for collection
  • UseParNewGC: no longer supported after JDK9, use the ParNew+Serial old collector combination for collection
  • UseConcMarkSweepGC: The default value in Server Mode prior to JDK 9 is collected using the combination of ParNew + CMS + Serial Old collector, which will be used as a backup collector for Concurrent Mode Failure of CMS collector
  • UseParallelGC: Recycle using the Parallel Avenge + Serial Old (PS MarkSweep) collector
  • UseParallelOldGC: Recycle using the Parallel Scavenge + ParallelOld collector
  • SurvivorRatio: specifies the capacity ratio between Eden and Survivor zones in the new generation. The default value is 8, indicating Eden:Survivor=8:1
  • PretenureSizeThreshold: Directly promotes to the object size of the previous generation. After this parameter is set, objects larger than this parameter will be allocated in the previous generation
  • MaxTenuringThreshold: Object age for promotion to the old age. After each Minor GC, the age of each object increases by 1, and when this parameter value is exceeded, the object enters the old age
  • UseG1GC: Use the G1 collector, which is the default Server mode after JDK 9
  • G1HeapRegionSize=n: Set the Region size, not the final value
  • MaxGCPauseMillis: set the target time of G1 collection process. The default value is 200ms, which is not a hard condition
  • GINewSizePercent: Sets the minimum G1 new generation value. The default value is 5%
  • GIMaxNewSizePercent: Sets the maximum new generation size of GG1. The default value is 60%

conclusion

There is a summary of the seven garbage collectors, as shown in the following table.

The collector Serial, parallel, concurrent New generation/old age algorithm The target Applicable scenario
Serial serial The new generation Replication algorithm Speed of response priority Client mode in a single-CPU environment
Serial Old serial The old s Mark-tidy Speed of response priority Backup plan for CMS in Client mode in single-CPU environment
ParNew parallel The new generation Replication algorithm Speed of response priority In a multi-CPU environment, it works with the CMS in Server mode
Parallel Scavenge parallel The new generation Replication algorithm Swallow star is preferred Computations in the background without much interaction
Parallel Old parallel The old s Mark-tidy Swallow star is preferred Computations in the background without much interaction
CMS concurrent The old s Mark-clear Speed of response priority Centralized on Internet sites or B/S system servers
G1 concurrent New generation/old age Mark-collation/copy algorithm Speed of response priority Server – oriented application, used to replace CMS