This article has been accepted by Github github.com/silently952…

Wechat official account: Beta learning Java

preface

In this article, we will take a detailed look at the common garbage collectors in the JVM and the characteristics of each garbage collector, which is often asked in interviews

Overview of JVM heap memory

Before we talk about garbage collectors, let’s take a look at how the JVM heap memory is partitioned, as shown below

  • Because the garbage collection algorithm used by virtual machines is a generational collection algorithm, the heap memory is divided into new generation and old generation
  • The garbage collection algorithm used by the new generation is the replication algorithm, so the new generation is divided into Eden and Survivor. The default space size ratio is 8:2
  • Survivor is divided into S0 and S1, whose space size ratio is 1:1

Memory allocation and garbage collection

  1. Objects are allocated first in the Eden region, and a Minor GC is triggered if the Eden region is full
  2. After Minor GC, objects that survive in Eden will be moved to S0. When S0 memory is full, a Minor GC will be triggered again. Objects that survive in S0 will be moved to S1, and S0 will be idle. After S1 is full, the surviving GC moves to S0 again in the Minor GC, and S1 is free, so that the age of the object increases by one year every GC. By default, the age of the object reaches 15 years old-XX:MaxTenuringThresholdSet up the
  3. Full GC is triggered when there is no room for objects that need to be sent to the old age after Minor GC (this step is not absolute, depending on the garbage collector)

The difference between Full and Minor GC: The Minor GC refers to the garbage collection behavior occurring in the new generation. Since objects are allocated in Eden area first and many objects die overnight, the trigger frequency is relatively high. Because of the replication algorithm, so the general recovery speed is very fast. Full GC is garbage collection that occurs in older generations and is typically 10 times slower than Minor GC; So you don’t want the JVM to have Full GC too often

The JVM does not have to be 15 years old in order to be able to accommodate different programs’ memory. If the total size of all objects of the same age in the Survivor zone is greater than half of the Survivor zone space, objects older than or equal to this age will enter the Survivor zone

Full GC trigger condition

  • Call in codeSystem.gc()
  • There is not enough space in the old era
  • The persistent area is out of space

Note: Large objects directly in the old s allocated memory, can through the parameter – XX: PretenureSizeThreshold the size of the control object, usually with large objects is a very long string or an array, if the distribution of a large group of large object is only temporary use, life is short, so will happen frequently Full GC, But there is room for the new generation; This should be avoided when writing code, especially when creating arrays

Space guarantee

When a Minor GC occurs in a new generation, the JVM checks to see if the contiguous space allocated in the old generation is greater than the sum of all objects in the new generation. If so, the Minor GC is safe to execute. If not, the JVM checks to see if the value of HandlePromotionFailure allows the space guarantee to fail. If so, the JVM checks to see if the amount of contiguous space available for older generations is greater than the average size of objects promoted to older generations. If so, Although this Minor GC is risky, the JVM will attempt a Minor GC; If guarantee failure is not allowed, then the JVM simply does Full GC

It is recommended that this parameter be turned on to avoid frequent Full GC by the JVM, although the guarantee may fail and result in a Full GC

Overview of garbage collector

As can be seen from the above picture:

  • New generation recyclers: Serial, ParNew, Parallel Insane
  • Garbage collectors for older generations: CMS, Serial Old, Parallel Old
  • G1 collector is suitable for new generation and old age
  • Representations that are connected to each other can be used in conjunction

CMS and Serial Old are both Old recyclers, why do they have a connection to each other?

Serial collector

This is a single-threaded collector, The oldest of its kind, and while it is doing garbage collection, all other threads must pause until The garbage collection is finished.

While Serial collectors have The problem of stopping The World, they tend to outperform other collectors in single-CPU environments where parallelism is weak; Because it is simple and efficient, there is no redundant thread interaction overhead; Serial is a good choice for VMS running in Client mode

Use the -xx :+UseSerialGC parameter to set the new generation to use this Serial collector

ParNew collector

The ParNew collector is a multithreaded version of the Serial collector; This is consistent with Serial except that it uses multiple threads for garbage collection. It defaults to starting the same number of threads as the number of CPU cores, which can be set with the -xx :ParallelGCThreads parameter.

As you can see from the figure above, the only collector that can work with CMS, besides Serial, is ParNew, so ParNew is usually the preferred next-generation garbage collector running in Server mode

Use the -xx :+UseParNewGC parameter to set the new generation to use this parallel collector

Parallel avenge

The Parallel Insane collector is still a new generation of multithreaded collectors using replication algorithms, which differ from The collector in that it is primarily concerned with throughput, while The other collectors are concerned with minimizing The wait time of user threads (Stop The World). Throughput = user thread execution time /(user thread execution time + garbage collection time). If the virtual machine runs for 100 minutes and garbage collection takes 1 minute, then the throughput is 99%

Shorter pause times are appropriate for applications that need to interact with the user, and a good response improves the user experience. The efficient throughput can make full use of CPU time to complete computing tasks as soon as possible, so the Parallel Insane collector is suitable for background computing task procedures.

-xx :MaxGCPauseMillis can control the maximum pause time for garbage collection. Be careful not to set this time too small to reduce the temporary garbage collection time, which can lead to frequent GC and reduce throughput

-xx :GCTimeRatio Sets the throughput. The value is an integer ranging from 0 to 100, that is, the garbage collection duration. The default value is 99, so the maximum garbage collection duration is 1%

-xx :+UseAdaptiveSizePolicy If this parameter is enabled, the JVM will enable THE GC adaptive adjustment policy without the need for the user to manually control the generation size, generation age, etc

Serial Old collector

The Serial Old collector is also a single-threaded collector for older generations that uses a mark-collation algorithm and can be used in Client mode in conjunction with the Serial collector.

It can serve as a fallback for the CMS collector in the event of Concurrent Mode Failure in the CMS. (CMS details later)

Parallel Old collector

The Parallel Old collector can be used in conjunction with the Parallel Scavenge collector to achieve “throughput first”, which is primarily targeted at older collectors and uses a mark-collation algorithm. This combination is preferred in throughput-focused tasks

-xx :+UseParallelOldGc Sets the old age to use the collector.

XX:+ParallelGCThreads Sets the number of threads for garbage collection.

CMS collector

CMS collector is a collector to obtain the shortest recovery pause time as the goal, in the Internet website, B/S architecture commonly used collector is CMS, because the system pause time is the shortest, to bring users a better experience.

-xx :+UseConcMarkSweepGC sets the old age to use the collector.

-xx :ConcGCThreads Sets the number of concurrent threads.

CMS adopts mark-clear algorithm, which is mainly divided into four steps:

  • Initialization mark
  • Concurrent tags
  • To mark
  • Concurrent remove

Stop The World still occurs when initializing tags and re-marking. Initializing tags only mark objects that GC Root can be directly associated with, which is faster. Concurrent tags can be executed concurrently with user threads. Re-marking is to correct garbage generated by user threads during concurrent marking, which is slightly longer than initial marking and much shorter than concurrent marking. The whole process is shown below

advantages

  • The CMS Collector is also called a Concurrent Low Pause Collector because of its main advantages: Concurrent collection and Low pauses.

disadvantages

  • The CMS collector is very sensitive to CPU 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 (or CPU resources). By default, the number of garbage collection threads started by CMS is (number of cpus +3) /4. That is, when the number of cpus is more than 4, garbage collection threads should occupy at least 25% of the CPU resources in concurrent collection, and the number of garbage collection threads decreases with the increase of the number of cpus. However, when there are less than four cpus (say, two), the CMS can have a significant impact on the user program. If the CPU is already heavily loaded and half of its computing power is allocated to the collector thread, the user program’s execution speed can suddenly be reduced by 50%, which is not acceptable.

  • Unable to handle floating garbage. As CMS concurrent cleanup phase user threads are still running, with the program running naturally there will be new garbage constantly generated. This part of the garbage appears after the marking process and the CMS cannot dispose of it in the current collection, leaving it for the next GC to clean up. This part of rubbish is called “floating rubbish”. Because the user thread needs to run during the garbage collection phase, there is still enough memory left for the user thread to use, so the CMS collector cannot wait until the old age is almost completely filled, as other collectors do. Recycling threshold can be through the parameter – XX: CMSInitiatingoccupancyFraction to set; If the collection threshold is set too high, a “Concurrent Mode Failure” will occur during the CMS run if large objects are allocated and insufficient space is not found, at which point the SerialOld GC will be temporarily started to restart the collection of the old age, resulting in a longer pause time.

  • The CMS is a collector based on a “mark-clean” algorithm, which means that a large amount of space debris is generated at the end of the collection. When space debris is too much, it will bring great trouble to the allocation of large objects. Often, there is surplus space in the old period, but it is impossible to find enough continuous space to allocate the current object. In order to solve this problem a CMS provides a parameter – XX: + UseCMSCompactAtFullCollecion, if enabled, open the memory when I was in Full GC defragmentation merging process, because the memory defragmentation process cannot be executed in parallel, so the pause time will be longer. Considering every FullGC must carry on the memory fragments merging is not very appropriate, so the CMS provides another parameter – XX: CMSFullGCsBeforeCompaction to control execution after how many times without defragmentation FullGC, defragmentation GC to a belt

G1 collector

G1 is a garbage collector for server-side applications.

  • Parallelism and concurrency: Like CMS, G1 can still perform garbage collection without suspending user threads, taking full advantage of multi-core CPUS
  • Generational collection: The concept of generational collection remains in G1, where it does not need to be used with other garbage collectors and can manage the entire heap memory independently
  • Spatial consolidation: The G1 uses a mark-de-clutter algorithm for the whole and a copy algorithm for regions, both of which mean that there is no need for memory defragmentation
  • Predictable pauses: Enables the user to specify how much time will be spent in garbage collection within a time segment.

Region

Although the concept of new generation and old generation is retained in G1, heap memory is organized in a completely different way by dividing the entire heap into many regions of the same size, and new generation and old are not physically contiguous memory regions, as shown in the following figure:

Each Region is marked with E, S, O, and H. H does not exist in previous algorithms and stands for Humongous. This means that these regions store huge objects. The Region memory size can be specified using -xx :G1HeapRegionSize. The Region memory size can be a power of 2, such as 1M, 2 m, 4M, or 8M

G1 GC mode

  • General-generation GC: Similar to other general-generation collectors, objects are preferentially allocated in Eden Region. If Eden Region is out of memory, the general-generation GC will be triggered and the surviving objects will be placed in survivor region or promoted to old region
  • Mixed GC: As more and more objects are promoted to the old region, the mixed GC will be triggered when the memory usage of the old generation reaches a certain threshold-XX:InitiatingHeapOccupancyPercentSet the threshold percentage, this parameter with CMS-XX:CMSInitiatingoccupancyFractionIs similar in function; The hybrid GC will recover the Cenozoic andPart of old memoryNote that it is part of the old age, not all of the old age; G1 tracks the garbage collection value of each Region and collects garbage from the Region with the highest value in the specified garbage collection period
  • Full GC: A full GC is triggered if the object memory allocation rate is too fast and the mixed GC has not been collected yet, causing the old age to fill up. G1’s Full GC algorithm is a single-threaded serial Old GC, which is similar to CMS, causing unusually long pause times and avoiding full GC as much as possible.

Write to the end (pay attention, don’t get lost)

There may be more or less deficiencies and mistakes in the article, suggestions or opinions are welcome to comment and exchange.

Finally, please friends don’t white piao I yo, I hope friends can point comment attention to three even, because these are all the power source I share 🙏


I have handwritten a simple version of SpringMVC from scratch, as well as the preparation of a detailed description of the document, I hope to help partners in-depth understanding of the core principle of SpringMVC, friends in need welcome to pay attention to the public number: Beta learning JAVA, reply to the source code