Home > Java > javaTutorial > JVM memory management------Garbage collector refined (allowing you to play with ease in the world of garbage collectors)

JVM memory management------Garbage collector refined (allowing you to play with ease in the world of garbage collectors)

黄舟
Release: 2016-12-28 15:51:34
Original
1135 people have browsed it

Introduction

In the previous chapter we have discussed the implementation of the garbage collector on hotspot. There are a total of six implementations and six combinations. This time LZ will discuss with you the power of each of these six collectors and the power of their combination.
In order to facilitate everyone's viewing and comparison, LZ decided to use the method used when writing the design pattern, focusing on certain collectors, to explain these collectors in several dimensions.

Client mode and server mode

Before introducing the content of this chapter, let me talk about the two modes of JVM, one is client mode and the other is server mode. The mode we usually use for development is client mode by default. You can also use the command line parameter -server to force server mode to be turned on. The biggest difference between the two is that the JVM has done a lot of optimizations in server mode.
JAVA applications in server mode start slowly, but due to the optimization of the JVM in server mode, the running speed will become faster and faster when the program runs for a long time. On the contrary, although JAVA applications in client mode start quickly, they are not suitable for long-term running. If the running time is long, the performance will be significantly lower than that of server mode.

Detailed explanation of collector

Let's first discuss the relevant content of a single garbage collector, and finally we will briefly talk about the characteristics of each combination after combination.

Serial Garbage Collector

Algorithm: Using copy algorithm
Memory area: Designed for the new generation
Execution method: single thread, serial
Execution process: When the new generation When the memory is not enough, all user programs are first suspended, and then a GC thread is started to use the copy algorithm to collect garbage. In this process, some objects may be promoted to the old generation.
Features: Due to single-thread operation, and the entire GC The user program must be paused at each stage, which will cause the application to pause for a long time, but it is very suitable for small-scale programs.
Applicable scenarios: Daily development and debugging program use, as well as desktop application interactive programs.
Open parameters: -XX:+UseSerialGC (client mode default value)

Serial Old Garbage Collector

Here we no longer list the characteristics of each dimension for the serial old collector, because it is related to The serial collector is the same, the difference is that it is designed for the old generation and therefore uses a marking/collation algorithm. For the rest of the dimension characteristics, serial old is exactly the same as the serial collector.

ParNew Garbage Collector

Algorithm: Using copy algorithm
Memory area: Designed for the new generation
Execution method: multi-threaded, parallel
Execution process: Current generation memory When it is not enough, first suspend all user programs, and then start several GC threads to use the copy algorithm to perform garbage collection in parallel. During this process, some objects may be promoted to the old generation.
Features: Multi-threads are used to run in parallel, so there will be It is sensitive to the number of core processors in the system. At least more than one processor is required. Several processors will open several threads (but the number of threads can be controlled using the parameter -XX:ParallelGCThreads=) , so it is only suitable for multi-core and multi-processor systems. Although the user program still needs to be paused during the entire GC phase, multi-threaded parallel processing will not cause too long a pause. Therefore, in terms of throughput, ParNew is greater than serial. The more processors, the more obvious the effect. But this is not absolute. For a single processor, the performance of ParNew will be lower than the serial collector due to the overhead of parallel execution (such as synchronization). Not only when using a single processor, but also when using a heap with a smaller capacity, or even when using two processors, the performance of ParNew is not necessarily higher than that of serial.
Applicable scenarios: On medium to large heaps, and the system has at least one processor
Enable parameters: -XX:+UseParNewGC

Parallel Scavenge Garbage Collector

This collector is almost identical to ParNew. They are both parallel collectors designed for the new generation and using replication algorithms. The biggest difference between it and ParNew is that the settable parameters are different, which allows us to more accurately control the GC pause time and throughput.
The parameters provided by the parallel scavenge collector mainly include controlling the maximum pause time (using -XX:MaxGCPauseMillis=), and controlling the throughput (using -XX:GCTimeRatio=). It can be seen from this that parallel scavenge is a collector that provides throughput control.
But don’t think that the smaller the maximum pause time, the better, or the larger the throughput, the better. When using the parallel scavenge collector, there are three main performance indicators, maximum pause time, throughput, and new generation area. the minimum value.
The parallel scavenge collector has a corresponding adjustment strategy. It will give priority to meeting the goal of maximum pause time, followed by throughput, and finally the minimum value of the new generation area.
Therefore, if you set the maximum pause time too small, you will sacrifice overall throughput and new generation size to satisfy your selfish desires. The palms and backs of our hands are full of flesh, so we'd better not do this. However, parallel scavenge has a parameter that allows the parallel scavenge collector to fully take over the adjustment of the memory area size. This also includes the age of promotion to the old generation (can be adjusted using -XX:MaxTenuringThreshold=n), that is, use -XX: UseAdaptiveSizePolicy turns on the memory area size adaptive policy.
The parallel scavenge collector can be turned on using the parameter -XX:+UseParallelGC. It is also the default new generation collector in server mode.

Parallel Old Garbage Collector

The relationship between Parallel Old and ParNew or Parallel Scavenge is like serial and serial old. The difference between them is not big, but parallel old is for old people. It is just a parallel collector designed in modern times, so it uses a mark/collation algorithm.
Another important significance of the Parallel Old collector is that it is the only old generation collector other than serial old that can work with parallel scavenge. Therefore, in order to avoid serial old affecting the reputation of parallel scavenge's controllable throughput , parallel old serves as a true partner of parallel scavenge.
It can be turned on using the parameter -XX:-UseParallelOldGC, but after JDK6, it is also the default old generation collector after turning on parallel scavenge.

Concurrent Mark Sweep Garbage Collector

The concurrent mark sweep (hereinafter referred to as CMS) collector is the only one that truly implements applications and GC threads working together (together for customers, And it is not necessarily true together, it may be a rapidly alternating collector.
CMS is a collector designed for the old generation and uses the mark/clear algorithm. It is also the only collector that uses the mark/clear algorithm in the old generation.
The mark/clear algorithm is used because of its special processing method. Its processing is divided into four stages.
1. Initial marking: It is necessary to pause the application and quickly mark the surviving objects.
2. Concurrent marking: Restore the application and track GC Roots concurrently.
3. Re-mark: It is necessary to pause the application and re-mark the objects missed by the tracking.
4. Concurrent clearing: Restore the application and clear unmarked garbage objects concurrently.
It is a bit more complicated than the original mark/clear algorithm, mainly manifested in the two phases of concurrent marking and concurrent clearing, and these two phases are also the longest phases in the entire GC phase. However, due to these two The stages are executed concurrently with the application, so the pause time caused by the CMS collector is very short. This is relatively easy to understand.
However, its shortcomings should be briefly mentioned, the main ones are as follows.

1. Since the GC thread and the application program will preempt CPU resources when executed concurrently, the overall throughput will decrease. In other words, in terms of throughput indicators, the CMS collector is weaker than the parallel scavenge collector. LZ here excerpts a description of CMS from the Oracle official website, which mentions the relationship between CMS performance and the number of CPUs.
Since at least one processor is utilized for garbage collection during the concurrent phases, the concurrent collector does not normally provide any benefit on a uniprocessor (single-core) machine. However, there is a separate mode available that can achieve low pauses on systems with only one or two processors; see incremental mode below for details.

LZ’s English is very average (I haven’t passed Level 4, shame, 0.0), but I can roughly translate it with the help of tools The meaning of this passage is as follows.
Chinese gist: Since garbage collection in the concurrent phase uses at least one processor, you will not gain any benefit from using a concurrent collector on a single processor. However, there is an independent way to effectively achieve low pauses on single or two-processor systems. See incremental mode below for details.
Obviously, Oracle's documentation points out that in the case of a single processor, the concurrent collector will cause performance degradation due to preemption of the processor. Finally, a way to deal with the incremental mode is given, but it is pointed out in the book "In-depth Understanding of the JAVA Virtual Machine" that the incremental mode has been defined as not recommended. Since the official introduction excerpted by LZ is based on the introduction of JDK5.0, and the book "In-depth Understanding of JAVA Virtual Machine" refers to the version of JDK6.0, LZ tentatively guesses that the incremental mode is in JDK6.0 It was abandoned when it was released, but the time or version of this abandonment is actually not important anymore.
2. A big disadvantage of mark/clear is the existence of memory fragmentation. Therefore, the JVM provides the -XX:+UseCMSCompactAtFullCollection parameter to perform defragmentation after the global GC (full GC). Since defragmentation after each global GC will greatly affect the pause time, the JVM also provides the parameter -XX:CMSFullGCsBeforeCompaction to control the defragmentation after several global GCs.
3. The last shortcoming of CMS involves a term---Concurrent Mode Failure. This is the official explanation for this term.
if the concurrent collector is unable to finish reclaiming the unreachable objects before the tenured generation fills up, or if an allocation cannot be satisfied with the available free space blocks in the tenured generation, then the application is paused and the collection is completed with all the application threads stopped.The inability to complete a collection concurrently is referred to as concurrent mode failure and indicates the need to adjust the concurrent collector parameters.
中文字幕:If the concurrent collector cannot complete before the old generation is filled, it is unreachable (unreachable) object recycling, or the effective free memory space in the old generation cannot satisfy a certain memory allocation request. At this time, the application will be suspended, and garbage collection will start during this suspension period. The application will not be resumed until the recycling is completed. . This failure to complete collection concurrently is called a concurrent mode failure, and the occurrence of this situation also means that we need to adjust the parameters of the concurrent collector.
The above two situations feel a bit repetitive. Isn't the failure to satisfy the memory allocation request caused by the failure to complete object recycling before the old generation is filled?
LZ’s personal understanding here is that the inability to complete object recycling before the old generation is filled up means that the old generation is not cleared in time during the concurrent clearing phase, resulting in insufficient free memory. The inability to satisfy memory allocation requests mainly refers to the fact that when the new generation is promoted to the old generation, due to too many memory fragments in the old generation, some allocations cannot be satisfied because there is no continuous memory.
In fact, when the concurrent mode fails, serial old will be used as an alternative collector to perform a global GC (Full GC), so serial old can also be regarded as a "substitute" for CMS. Obviously, due to the intervention of serial old, a large pause time will be caused.
In order to avoid concurrent mode failures as much as possible, we can adjust the -XX:CMSInitiatingOccupancyFraction= parameter to control how much memory usage of the old generation reaches (N%), and then start the concurrent collector to start recycling. old generation.

The power of combination

We have briefly introduced the characteristics of each collector above. Below, LZ will share with you three typical combinations. The other three combinations are generally not commonly used.

serial & serial old

This combination is one of our most common combinations and is also the default garbage collector combination in client mode. It can also be forced to turn on using the parameter -XX:+UseSerialGC.
Because it is relatively simple to implement and has no additional thread-related overhead (mainly thread switching and synchronization), it is very suitable for small applications running on the client PC, or desktop applications (such as user interface programs written in swing) , as well as our usual development, debugging, testing, etc.
The above three situations all have common characteristics.
1. Since they are all run on PC, the configuration is generally not too high, or the number of processors is not too many.
2. The applications in the above situations will not run for too long.
3. The scale will not be too large, that is to say, the heap is relatively small, the collection is relatively fast, and the pause time will be relatively short.

Parallel Scavenge & Parallel Old

This combination is not common for us. After all, it does not appear in our usual development, but it is a combination that requires high throughput. Or it is the first choice for applications that do not require high pause time, and this combination is the default combination in server mode (JDK6 or after JDK6). Of course, it can also be forcibly turned on using the -XX:+UseParallelGC parameter.
This combination uses parallel collection in both the new generation and the old generation, so the pause time is shorter and the overall throughput of the system is higher. It is suitable for some background programs that need to run for a long time and have certain requirements on throughput.
These programs running in the background have the following characteristics.
1. The system configuration is relatively high, usually at least four cores (based on the current hardware level).
2. The throughput requirements are high, or a certain amount needs to be reached.
3. The application takes a long time to run.
4. The application size is large, usually a medium to large heap.

ParNew & CMS (Serial Old as a substitute)

This combination is the same as the above parallel combination. It is not common in daily development, and it is for response time. First choice for more demanding applications. This combination needs to be enabled using the parameter -XX:+UseConcMarkSweepGC.
This combination uses a parallel collector in the new generation, so the GC speed of the new generation will be very fast and the pause time will be very short. The GC of the young generation uses concurrent collection. During most of the garbage collection time, the GC thread is executed concurrently with the application, so the pause time is still very short. It is suitable for some background programs that need to run for a long time and have certain requirements on corresponding time.
The characteristics of these programs running in the background are very similar to the background programs in parallel mode. The difference is the second point. Background applications using the combination of ParNew & CMS generally have certain requirements on response time. The most typical This is our WEB application.

Conclusion

This time LZ has sorted out the characteristics of each collector and the characteristics of each combination. In addition, there are three remaining combinations that LZ has not mentioned here. The reason is that these three combinations are not particularly commonly used, or it can be said that they are hardly used. These three combinations all give people a different feeling, and the effect is indeed not good.
I hope this article can bring you some help, thank you for watching.

The above is the content of JVM memory management------garbage collector refinement (allowing you to play with ease in the world of garbage collectors). For more related content, please pay attention to the PHP Chinese website (www .php.cn)!


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template