Hello, today for you children to share JVM, quickly take out a small notebook to write down!

Garbage collection scenario Generation GC scenario In the JVM memory model, the generation of memory is divided into Eden and two Survivor

When the system is running continuously, the Eden area will fill up, and then the Minor GC will be triggered. There will be a special garbage collection thread for garbage collection. Different memory areas will have different garbage collectors, which means that the garbage collection thread and garbage collector can work together and use their own garbage collection algorithm. Garbage collection is performed on the specified memory region, as shown in the following figure:

For the new generation using ParNew garbage collector to recycle, and then ParNew garbage collector for the new generation is the replication algorithm to recycle garbage

The garbage collector will mark all survivable objects in Eden and pass them all to Survivor1, then empty Eden’s garbage objects once

When Eden is filled up again, the Minor GC will be fired again, and the garbage collector thread will run the algorithm logic in the garbage collector, that is, copy the algorithm logic, to mark the survivable objects in Eden and Survivor1, and then transfer the survivable objects to Survivor2 once and for all. Then reclaim garbage objects in Eden and Survivor1

Can our written JAVA system continue to create new objects in the new generation at runtime when GC occurs?

If new objects are allowed to be created during GC, then the garbage collector is transferring the surviving object markers in Eden and Survivor1 to Survivor2, and then trying to clean up the garbage objects in Eden and Survivor1. As a result, the system program is still creating new objects in Eden at this time, and these new objects soon become garbage objects. Some people refer to them as living objects, which is completely confusing to garbage collector, and new objects are still being created while recycling.

Stop the World

The JVM’s biggest pain point is the garbage collection process, during the garbage collection process, as much as possible to let the garbage collector concentrate on the work, do not let our Java application continue to create objects, so the JVM will enter the “Stop the World” state in the background. This means that all worker threads on our Java system will be stopped and our code will no longer run

In this way, we can stop the system from creating new objects and let the garbage collection thread finish the garbage collection as soon as possible, which is to mark and transfer Eden and survivable objects of survivable 1 to survivable 2. Then reclaim the garbage objects in Eden and Survivor1 as soon as possible. After the garbage collection is completed, resume the worker thread of the Java system we wrote and continue to run our code logic to create new objects in Eden

Stop the World System stops

When running the GC will be unable to create a new object, will build the car system halt, if a Minor GC to run 50 ms, could cause our system can’t accept any requests within 50 ms, user initiated during the 50 ms all requests will appear short of card, because the system of worker threads is not running, cannot handle the request

Due to improper memory allocation, objects frequently enter the old age, with an average of seven or eight minutes of Full GC, while Full GC is relatively slow, and a collection may take several seconds or even tens of seconds. Therefore, once Full GC is frequent, the system will be stuck for tens of seconds every few minutes, making the user experience very poor

Therefore, whether it is the new generation GC or the old GC, try not to make the frequency too high, and avoid the duration too long, so as not to affect the normal operation of the system, this is the most need to optimize in the process of using the JVM, and also the biggest pain point.

Serial uses one thread to collect garbage and then suspends the system worker thread

We rarely use this approach in server applications

ParNew Garbage Collector (New generation)

Commonly used new generation garbage collector

For the server is generally multi-core CPU optimization, he is to support multi-thread garbage collection, can greatly improve the performance of recycling, shorten the time of recycling

Garbage collector

Serial and Serial Old garbage collectors

Used to recycle new generation and old age garbage objects respectively

The working principle is single thread running, garbage collection will stop our own writing system of other threads, let our system directly stuck, and then let them garbage collection, this is now generally write background Java system almost no use.

ParNew and CMS garbage collector ParNew is now commonly used in the new generation of garbage collectors, using the replication algorithm to collect garbage

CMS is the old garbage collector

Both are multi-threaded concurrent mechanisms with better performance, and are now generally standard combinations of online production systems

ParNew

The theory of

In the absence of the latest G1 garbage collector, the ParNew garbage collector is often used as the new generation of garbage collector online. But even with G1, many online systems still use ParNew

Generally, Java systems running on the server can take full advantage of the multi-core CPU of the server. If the new generation is recycled, only single thread is used for garbage collection, which will lead to a waste of CPU resources

The new generation of ParNew garbage collector is the main multi-thread garbage collection mechanism, another kind of Serial garbage collector is the main single-thread garbage collection mechanism, they are both the new generation of garbage collection, the only difference is the difference between single-thread and multi-thread, but the garbage collection algorithm is exactly the same

If the ParNew garbage collector executes a Minor GC at the appropriate time, it stops all the worker threads of the system program, forbids the program to continue to create new objects, and then collects the garbage itself with multiple garbage collection threads, using the same mechanism and algorithm

Parameter Settings When deployed to Tomcat, you can set Tomcat JVM parameters in Tomcat catalina.sh. You can also specify JVM parameters during Tomcat startup using Spring Boot.

Specify the use of the ParNew garbage collector

With the “-xx :+UseParNewGC” option, once this option is added, the garbage collector for the new generation after JVM startup is ParNew

ParNew The default number of threads for the garbage collector

Once we specify the ParNew garbage collector, it defaults to setting itself the same number of garbage collection threads as the number of CPU cores

If you must adjust the number of garbage collection threads for ParNew yourself, you can do so by using the “-xx :ParallelGCThreads” parameter, which allows you to set the number of threads

CMS

The garbage collector chosen by the old generation is CMS, which uses the tag cleaning algorithm

Tag cleaning algorithm: first through GC Roots method, see if each object is referenced by GC Roots, if so, it is a live object, otherwise it is garbage object. The biggest problem with this method is that it will cause a lot of memory fragmentation. This kind of memory fragmentation is not large enough to fit any object, which will cause memory waste

CMS STW(Stop the World) problem: If you Stop all worker threads and slowly execute the “mark-clean” algorithm, the system will be stuck for a long time and many responses cannot be processed. Therefore, the CMS garbage collector adopts the mode that the garbage collector thread and the system worker thread execute simultaneously as much as possible

How to realize garbage collection while the system works? CMS performs a garbage collection process in four stages:

Initial tag

Concurrent tags

To mark

Concurrent cleaning

1. Initial tag CMS performs the initial tag phase before garbage collection. At this stage, The system’s worker threads will all Stop and enter The “Stop The World” state. The initial tag execution of STW has little impact because it is fast and only marks objects directly applied by GC Roots

2. Concurrent marking this stage will allow the system to create all kinds of new objects at will and continue to run. During running, new living objects may be created, or some of the living objects may lose reference and become garbage objects. In this process, the garbage collection thread will try its best to trace the GC Roots of the existing objects, but in this process, the system program will not stop working during the concurrent marking, it may create various new objects, some objects may become garbage

This stage is to trace all objects in the old age by GC Roots, which is actually the most time-consuming. It needs to trace whether all objects are referenced by GC Roots from the root. However, this stage is run concurrently with the system program, so in fact, this stage will not affect the system operation.

Because in stage 2, you mark live objects and garbage objects while the system is constantly creating new objects and making old objects garbage, there will definitely be a lot of live objects and garbage objects at the end of Stage 2 that were not marked in stage 2. So now enter the third stage, to continue to Stop the system program, ** again enter the “Stop the World” phase. ** Then re-mark some of the newly created objects in the second paragraph, and some of the existing objects may lose references and become garbage

This re-marking phase is very fast. It actually marks the few objects that have been changed by the system program in the second phase, so it runs very fast, and then resumes the system program.

4, concurrent cleaning let the system program run at will, and then he came to clean up the previous marked as garbage object, this stage is time-consuming, the need to clean up the object, but he is followed by the system program run concurrently, so it does not affect the execution of the system program

CMS garbage collector has one of the biggest problems, although it can make the system work at the same time in the garbage collection at the same time, in the two most time-consuming stages of concurrent marking and concurrent cleaning, garbage collection thread and system worker thread work at the same time, This results in limited CPU resources being partially consumed by garbage collection threads

During concurrent marking, GC Roots need to be deeply traced to see how many people in all objects are alive. However, since there are many living objects in the old days, this process will track a large number of objects, so it takes a lot of time. Concurrent cleanup, which involves cleaning up garbage objects from various random memory locations, is also time consuming

So the CMS garbage collection thread is CPU intensive in these two phases. The default number of garbage collection threads started by CMS is (CPU cores + 3) / 4

In the Concurrent cleanup stage, CMS is just recycling the garbage objects marked before, but the system has been running at this stage, and some objects may enter the old age as the system runs, and also become garbage objects, which are “floating garbage”. Because it becomes garbage, the CMS can only collect garbage objects that were marked before, not until the next GC. So to ensure that there is enough memory for some objects to age during the CMS garbage collection, some space is usually reserved. One of the triggers for CMS garbage collection is to automatically perform GC when the memory footprint of the old generation reaches a certain percentage.

“- XX: CMSInitiatingOccupancyFaction” parameters can be used to set the old s occupies much proportion of trigger CMS garbage collection, JDK 1.6, the default value is 92%

That is, if the old generation takes up 92% of the space, the CMS garbage collection is automatically performed, reserving 8% of the space for concurrent collection while the system program puts some new objects into the old generation.

So what happens if, during the CMS garbage collection, the system program puts older objects into the system than the available memory space?

A Concurrent Mode Failure occurs when Concurrent garbage collection fails and you run out of memory while I collect objects

In this case, the CMS will be automatically replaced with the Serial Old garbage collector, which is to directly force the system program “Stop the World” to re-trace GC Roots for a long time, mark all garbage objects, do not allow new objects to be generated, and then recycle all garbage objects at once. Then resume the system thread

3. Memory fragmentation Problem In the old CMS, the “mark-clean” algorithm is used to mark garbage objects every time and recycle them at a time, which will lead to a large number of memory fragmentation. If there is too much fragmentation, subsequent objects will run out of contiguous memory space in the old age, and the Full GC will be triggered

So CMS is not entirely mark-clean, because too much memory fragmentation can actually lead to more frequent Full GC

CMS has a parameter is “- XX: + UseCMSCompactAtFullCollection”, the default is open, mean after Full GC to “Stop the World”, again to Stop the worker thread, and then to defragment, is to move the live objects together, Free large contiguous memory space to avoid memory fragmentation

And a parameter is “- XX: CMSFullGCsBeforeCompaction”, how many times this meaning is to perform Full GC then perform a memory defragmentation job, the default is 0, which means that every time after a Full GC on a memory consolidation

1. The available memory of the old generation is smaller than the size of all objects of the new generation. If the space guarantee parameter is not enabled, the Full GC will be triggered directly, so the general space guarantee parameter will be turned on.

2. The available memory of the old age is less than the average object size of the old age after the previous generation GC, so the Full GC will be performed in advance;

If the Survivor of Minor GC is greater than that of Survivor, then the old age is out of memory.

4, – XX: CMSInitiatingOccupancyFaction: old s have used memory is greater than the setting threshold, will trigger a Full GC.

5. Display calls to system.gc

What is the pain point brought to us by ParNew + CMS? Stop the World, this is the most painful point for everyone

Both the new generation garbage recycling and the old garbage recycling will more or less produce the phenomenon of “Stop the World”, which has a certain impact on the operation of the system. So, in fact, the subsequent optimization of the garbage collector is aimed at reducing “Stop the World”.

From this foundation, the G1 garbage collector was born, which can provide better garbage collection performance than the “ParNew + CMS” combination

G1 garbage collector

Features THE G1 garbage collector can collect both new and old objects at the same time, it does not need two garbage collectors to work together, he can do all the garbage collection.

1. Split the Java heap memory into regions of equal size

G1 also has new generation and old generation concepts, but they are only logical concepts

That is, the Cenozoic might contain some regions, and the old might contain some regions.

You can set an expected pause time for garbage collection

In other words, we can directly control the impact of garbage collection on system performance by specifying, for example, that we want G1 garbage collection to ensure that the “Stop the World” time caused by G1 garbage collection does not exceed 1 minute during garbage collection

3, Region may belong to the Cenozoic era or the old age

First Region probably doesn’t belong to anyone, and then assigned to the new generation, and then put a lot of belongs to a new generation of object, then triggers garbage collection in this Region, and the next one and the same Region could be allocated and old age, for the old s long life cycle of the object, so in fact in the G1 corresponding memory model, A Region belongs to both the new generation and the old generation, so there is no such thing as how much memory the new generation gives or how much memory the old generation gives

In fact, the new generation and the old generation’s respective memory areas are constantly changing, which is automatically controlled by G1

How does G1 control system pauses caused by garbage collection? In order for G1 to do this, it must track the reclaimed value of each Region. What is the reclaimed value?

He has to figure out how many of the objects in each Region are garbage, how long it takes to garbage collect a Region, and how much garbage can be collected. G1 finds that garbage objects in one Region have 10MB and it takes 1 second to reclaim them. Garbage objects in another Region have 20MB and it takes 200 milliseconds to reclaim them.

During garbage collection, G1 will find that garbage collection has stopped the system for hundreds of milliseconds in the last period of time, such as 1 hour. Now, it must be the Region in the figure above that only takes 200ms to reclaim 20MB garbage. G1 then triggers a garbage collection, which may cause the system to pause for 200ms, but at one time collects more garbage, 20MB of garbage

So in simple terms, the G1 can let you to set the garbage collection system, the influence of his own by split the memory for a large number of small Region, and to track each Region can be recycled in the size of the object and the estimated time, finally in garbage collection, try to put the garbage on the system the effects of the control in your specified time range, At the same time, try to recycle as many garbage objects as possible in the limited time. This is the core design of the G1

How do I set the memory size for G1? G1 corresponds to a large number of Region memory regions. Each Region has the same size and is automatically calculated and set by default. You can set a size for the entire heap memory, for example, -xms and -xmx

When the JVM starts, the G1 garbage collector is used (via: The JVM can have up to 2048 regions. The Region size must be a multiple of 2, such as 1MB, 2MB, 4MB, etc. This can be specified manually. “- XX: G1HeapRegionSize is * * * *

Initially, the default size of the new generation in the heap is 5%. This can be set by “-xx :G1NewSizePercent”

When the system is running, the JVM will continuously add more regions to the new generation, but the proportion of the new generation will not exceed 60%. You can use the “-xx :G1MaxNewSizePercent” command. Once the new generation Region is garbage collected, the number of new generation regions will be reduced. These are all dynamics

And the concept of Eden and Survivor? Although G1 divides memory into many regions, there are still new generation and old generation, and there are Eden and Survivor divisions in the new generation

By setting “-xx :SurvivorRatio=8”, 80% of the new generation regions belong to Eden and 10% of the two Survivor regions belong to Eden respectively

As objects are continuously allocated in the new generation, the number of regions belonging to the new generation will continue to increase, and so will the number of regions corresponding to Eden and Survivor

G1 New Generation garbage collection trigger mechanism? Since G1 Cenozoic generation also has the classification of Eden and Survivor, the mechanism for triggering garbage collection is similar. As objects are continuously placed in the Region corresponding to the Eden of the Cenozoic generation, the JVM will continuously add more regions to the Cenozoic generation until the Cenozoic generation occupies a maximum proportion of 60% of the heap size.

Once the Cenozoic generation reaches 60% of the maximum heap size, the Cenozoic GC is still triggered, and G1 enters a “Stop the World” state for garbage collection using the replication algorithm described earlier. Then, put the living objects in Eden’s Region into S1’s Region, and reclaim the garbage objects in Eden’s Region. However, this process is different from the previous one, because G1 can set the target GC pause time. This is the maximum amount of time G1 can pause the system while GC is being performed. This can be set with the “-xx :MaxGCPauseMills” parameter. The default value is 200ms.

G1 then tracks how long it takes for each Region to reclaim and how many objects it can reclaim to select a part of the Region and ensure that the GC pause time is controlled within the specified range, so as to reclaim as many objects as possible.

When does the object enter the old age? It can be said that it is almost the same as before, with the following conditions:

1. The object has escaped many times of garbage collection in the new generation and has reached a certain age. Parameter “-xx :MaxTenuringThreshold” can be set to this age and it will enter the old age

2. Dynamic age rule, if once a Cenozoic GC is found, the number of surviving objects exceeds 50% of Survivor

In G1’s memory model, large objects can be stored in special regions instead of old regions.

In G1, the rule for determining large objects is that a large object exceeds 50% of the size of a Region. If each Region is 2MB, a large object that exceeds 1MB will be added to a Region dedicated for large objects. If a large object is too large, It may be stored across multiple regions in the new generation and the old generation, and will be recycled along with the large object Region

Well, today’s article is here, I hope to help you confused screen!