Garbage collection strategy, setup and tuning for hotspot

We all know that JVM memory consists of several parts :  Java stack, program counter (ProgramCounter) register, native method stack, heap, method area, and running constant pool.

JVM garbage collection is only performed for the common memory areas: heap and method areas .

This article mainly discusses two points, one is the garbage collection strategy , and the other is the tuning method.

1. Garbage collection mechanism

1.1 Generation Management

The heap and method areas are divided according to the different times when the objects appear:

u Objects are frequently created in the heap. Based on a generational idea, the heap is divided into two parts: the new generation and the old generation according to the object survival time . We cannot garbage collect the objects that survive in the new generation and put them into the old generation. , but the objects that survive after several GCs are put into the old generation, so we divide the new generation into the Eden area and the two Survivor areas again, so that the objects are created in the Eden area, and then in the two Repeated replication between survivors, and finally the objects that are still alive are copied to the old generation.

The u   method area stores constants, loaded bytecode file information, etc., and the information is relatively stable. Because objects are not created frequently, there is no need for generation, just GC.

Therefore, the range to be scanned by our JVM garbage collection is:

Note: The picture comes from the Internet

Cenozoic:

1. All new objects are created in the Eden area. After the Eden area is full, the minor GC on the new generation is triggered, and the surviving objects in the Eden area and the non-idle Survivor area are copied to another free Survivor area.

2. Always ensure that a Survivor is empty, the new generation minor GC is to copy surviving objects between the two Survivor areas until the Survivor area is full.

Old generation:

1. When the Eden area is full, the minor GC is triggered to copy the surviving objects to the Survivor area. When the Survivor area is full, the minor GC is triggered to copy the surviving objects to the old generation.

2. After multiple replications between the two Survivors of the new generation, the objects that still survive are relatively old and can be put into the old generation. As time goes by, if the old generation is full, A Full GC will be triggered to perform garbage collection on the entire heap (with young, old, and persistent generations).

Endurance:

If the persistent generation is full, a Full GC will be triggered

1.2 Garbage Collection

The key to executing gc lies in two points, one is to detect garbage objects , and the other is to release the space occupied by garbage objects .

1.2.1 Detecting garbage objects

There are generally two algorithms for detecting garbage objects :

1. Reference counting

2. Accessibility Analysis

The reference counting method is basically not used because it cannot detect the problem of mutual circular references between objects. The main method of detecting garbage objects in the garbage collection of mainstream languages ​​is the "reachability analysis" method. The following also mainly introduces the JVM accessibility analysis method to detect garbage objects.

"Reachability Analysis" Algorithm Description?

A series of objects named "GC Root" are used as the starting point to search downward from these nodes. The path traversed by the search is called the Reference Chain. When an object is not connected to the GC Root by any reference chain, Then the object is unreachable, the object is unusable, and the garbage collector will reclaim the memory occupied by it . Therefore, the principle that the JVM judges that an object needs to survive is: an object that can be reached by a root object.

What is reachable?

That is, object A refers to object B, then it is called reachable from A to B.

Collection of GCRoot objects?

a. The referenced object in the Java virtual machine stack (local variable table in the stack frame).

b. Objects referenced by class static properties in the method area.

c. Objects referenced by constants in the method area.

d. The reference object of the JNI native method in the native method stack.

1.2.2 Free up space

1. Garbage collection algorithm

How to detect garbage objects has been described above. After garbage objects are detected, memory recovery needs to be performed according to a specific garbage collection algorithm . Common garbage collection algorithms are:

uCopying   _

uMark   -Sweep

uMark   -Compact

u   Generational Collection, implemented with the help of the first three algorithms

I won't go into details here, if you are interested, you can Baidu by yourself.

2. Garbage collector implementation

The above algorithms are theoretical things. The Java Virtual Machine Specification does not specify how the garbage collector is implemented. Therefore, the garbage collectors provided by different manufacturers and different versions of virtual machines may be different. The following lists the six garbage collector implementations provided by the HotSpot (Sun JDK and Open JDK) virtual machines:

collector name

Application target

Algorithm

import version

Operation mode

Serial

Cenozoic

replication algorithm

Before Jdk1.3.1

serial, single thread

ParNew

Cenozoic

replication algorithm

 

parallel, multithreaded

Parallel Scavenge

Cenozoic

replication algorithm

Jdk1.4

parallel, multithreaded

Serial Old

Paleozoic

Mark-Organize

 

serial, single thread

Parallel Old

Paleozoic

Mark-Organize

Jdk1.6

parallel, multithreaded

CMS

Paleozoic

mark-clear

Jdk1.5

concurrent, multithreaded

Parallel: Multiple garbage collection threads work in parallel, while user threads are still waiting.

Concurrent (Concurrent): The garbage collection thread and the user thread work at the same time for a period of time (not in parallel, but alternately).

Summarize:

1. Two serial collectors, three parallel collectors, and one concurrent collector.

2. The ParNew collector is a multithreaded version of Serial.

3. Serial Old collector is the old generation version of Serial collector.

4. The Parallel Scavenge collector targets throughput and is suitable for tasks that operate in the background without much interaction.

5. The Parallel Old collector is the old generation version of Parallel Scavenge.

6. The Parallel Scavenge collector and the Parallel Old collector are a veritable "throughput first" combination.

7. Except for CMS, other collectors need to suspend all other threads when working. CMS is the first real concurrent (Concurrent) collector. For the first time, the garbage collector thread and user thread work at the same time. It is a collector with the shortest pause time as the goal, which is suitable for scenarios with more interaction, which is also the difference from the Parallel Scavenge/Parallel Old throughput priority combination.

8. The new generation adopts the mark-copy method because there are few objects left by recycling.

9. The old generation uses the mark-sweep/mark-sort algorithm because there are many objects left behind by recycling.

3. Select the desired garbage collector

The virtual machine provides parameters so that users can set the required garbage collector according to their needs:

JVM running parameters

Cenozoic

Paleozoic

-XX:+UseSerialGC (Client mode default)

Serial

Serial Old

-XX:+UseParNewGC

ParNew

Serial Old

-XX:+UseConcMarkSweepGC

ParNew

CMS (Serial Old standby)

-XX:+UseParallelGC (default value in Server mode)

Parallel Scavenge

Serial Old

-XX:+UseParallelOldGC

Parallel Scavenge

Parallel Old

2. Performance tuning

2.1 Purpose of performance tuning

Reduce the frequency of minor gc and the number of full gc.

2.2 Means of performance tuning

1. Use the memory viewing tools provided by JDK , such as JConsole and Java VisualVM

2. Control the proportion of each part of the heap memory

3. Use a suitable garbage collector

Means 1: Memory viewing tools and GC log analysis

n -verbose.gc: Displays the operation content of GC. Turn it on to display when the busiest and most idle collection behavior occurs, the amount of memory before and after collection, the time it takes to collect, and more.

n -xx:+printGCdetails: Learn more about changes in GC.

n -XX:+PrintGCTimeStamps: Know when these garbage collections occurred, measured in seconds since the JVM started.

n -xx:+PrintHeapAtGC: Learn more about the heap.

Method 2: For the ratio of the new generation to the old generation

If the new generation is too small, it will cause frequent GC , and the large object will directly enter the old generation and cause full gc

If the new generation is too large, it will induce the full gc of the old generation , and the gc time of the new generation will be prolonged

It is recommended that the new generation occupies 1/3 of the entire heap. The relevant JVM parameters are as follows:

n -Xms: initial heap size

n -Xmx: maximum heap size

n - Xmn: young generation size

n -XX:PermSize=n: Persistent generation maximum value

n -XX:MaxPermSize=n: Persistent generation maximum value

n -XX:NewRatio=n: Set the ratio of the new generation to the old generation. For example, it is 3, which means that the ratio of the new generation to the old generation is 1:3, and the new generation accounts for 1/4 of the sum of the old generation and the new generation.

Means 3: The ratio for Eden and Survivor

If Eden is too small, it will cause frequent GC .

If Eden is too large, large objects will directly enter the old generation , reducing the survival time of objects in the new generation.

n -XX:SurvivorRatio=n: The ratio of the Eden area to the two Survivor areas in the Cenozoic. Note that the Survivor area has two. For example: 3 means Eden: Survivor=3:2, a Survivor area occupies 1/5 of the entire young generation

n -XX:PretenureSizeThreshold: The size of the object directly into the old generation. After setting this value, objects larger than this parameter will be allocated memory directly in the old generation.

n -XX:MaxTenuringThreshold: The age at which the object is transferred to the old generation. After each object undergoes a new generation GC (Minor GC), the age is incremented by 1. After the set value is exceeded, the object is transferred to the old generation.

Tactic 4: Use the Right Garbage Collector

The garbage collector used by the JVM parameter setting refers to the previous introduction, and here are some other settings.

Parallel collector settings

n -XX:ParallelGCThreads=n: Set the number of parallel collection threads when the parallel collector collects.

n -XX:MaxGCPauseMillis=n: Sets the maximum pause time for parallel collection, only valid for ParallelScavenge.

n -XX:GCTimeRatio=n: Set the percentage of garbage collection time in the program running time, only valid for Parallel Scavenge.

Concurrent collector settings

n -XX:CMSInitiatingOccupancyFraction: By default, the CMS collector will be activated after the old generation uses 68% of the space. This parameter is to trigger garbage collection after setting how much the old generation space is used. Note that if the memory reserved during CMS operation cannot meet the needs of the program, concurrent mode failure will occur, and the Serial Old collector will be enabled as a backup for old generation garbage collection.

n -XX:+UseCMSCompactAtFullCollection: Excessive space fragmentation is a drawback of the mark-sweep algorithm. This parameter is set to perform a defragmentation process after FULL GC.

n -XX:CMSFullGCsBeforeCompaction: set to start a memory defragmentation after several garbage collections

Third, the actual project configuration

 

1. Modify the tomcat\bin\Catalina.bat file
under Windows environment:

 

在166行左右
rem Execute Java with the applicable properties ”以下每行
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%

Add -Xms256m -Xmx512m after %DEBUG_OPTS%

Under linux environment:

Open the catalina.sh file in the bin file of the Tomcat installation directory and enter the editing state.
Add the following script after the comment:
JAVA_OPTS='-Xms512m -Xmx1024m'
JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=64M -XX :MaxPermSize=256m"

where JAVA_OPTS='-Xms512m -Xmx1024m' is to set the size of the memory used by Tomcat.

-XX:PermSize=64M -XX:MaxPermSize=256m Specify the memory size of the class space (for loading classes) 

 

After saving, run tomcat again in the command line mode, and then check whether the change has been successful through the method of how to observe the existing memory of tomcat introduced at the end.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326333893&siteId=291194637