Sorting out some JVM knowledge points caused by recycling algorithm & trigger condition & GC (Allocation Failure)

I checked the log of a certain program a few days ago and found that GC-related information has been reported. I am not sure whether such information is correct or incorrect, so I took this opportunity to review the GC-related content:

Take one of the behavior examples to interpret the log information:

[GC (Allocation Failure) [ParNew: 367523K->1293K(410432K), 0.0023988 secs] 522739K->156516K(1322496K), 0.0025301 secs] [Times: user=0.04 sys=0.00, real=0.01 secs]

GC

Indicates that a garbage collection has been performed. There is no Full modification in front, indicating that this is a Minor GC. Note that it does not mean that only the young generation is GC , and the existing ones will be STW regardless of whether it is the young or old .

Allocation Failure

It shows that the reason for this GC is because there is not enough space in the young generation to store new data.

ParNew

Indicates that this GC occurred in the young generation and the ParNew garbage collector was used . ParNew is a multi-threaded version of the Serial collector that uses multiple CPUs and threads to complete garbage collection ( the number of threads used by default is the same as the number of CPUs , and you can use the -XX: ParallelGCThreads parameter limit). The collector uses a copy algorithm to reclaim memory, during which it will stop other worker threads, namely Stop The World.

367523K->1293K(410432K) : The unit is KB

The three parameters are: the used capacity of the memory area (here, the young generation) before GC, the used capacity of the memory area after GC, and the total capacity of the memory area.

0.0023988 secs

GC time spent in this memory area, in seconds

522739K->156516K(1322496K)

Three parameters are: the heap area size before garbage collection, the garbage collection heap size of the area, the size of the heap Chief.

0.0025301 secs

The memory area (here is the entire heap) domain GC time, in seconds

[Times: user=0.04 sys=0.00, real=0.01 secs]

 Respectively represent the user mode time-consuming, kernel mode time-consuming and total time-consuming

The analysis can draw conclusions:

    The new generation of GC reduced by 367523-1293=366239K

    A total of 522739-156516=366223K has been reduced in the Heap area

366239 – 366223 = 16K, which means that a total of 16K memory was moved from the young generation to the old generation. It can be seen that the number is not large, indicating that they are all objects with a short life cycle, but there are many such objects.

  What we need is to avoid the occurrence of Full GC as much as possible, so that the objects are collected in the young generation as much as possible , so here we can slightly increase the size of the young generation, so that the 17K data is also stored in the young generation.

GC time, with which the object is determined what method is required recovery:

  1. Reference counting method (no longer used)
  2. Accessibility analysis

In short, the former is to add a reference counter to the object. This counter is +1 when there are other references, -1 when the reference is invalid, and it can be deleted when it is 0. But it cannot solve the problem of circular references, so the latter algorithm is generally used.

The basic idea of ​​the reachability analysis method is to use a series of objects named GC Roots as the starting point, starting from these nodes and searching downwards. The path traversed by the search is called the Reference Chain. When an object reaches the GC When Roots is not connected by any reference chain, the object is proved to be unusable, and it can be recycled.

GC Roots are generally references from outside the heap to inside the heap , for example:

  1. Objects referenced in the JVM stack
  2. Objects referenced by static properties in the method area
  3. Objects referenced by constants in the method area
  4. Objects referenced in the local method stack 

 

Take CMS as an example to add some knowledge points:

Introduction to the replication algorithm:

Because the life cycle of new generation objects is generally very short, the memory area is generally divided into three parts, one large is called Eden, and two small is called Survivor. The ratio between them is generally 8:1:1.

Only use Eden + one piece of Survivor when using it. When the Eden area is full, a minor gc will be performed , and the objects below the survival will be copied to another Survivor . If another piece of Survivor cannot be put down (the corresponding virtual machine parameter is XX:TargetSurvivorRatio, the default is 50, which is 50%) , maxThresholdAge is updated from 15 to the current object and increments the age value of the object at the same time, and the object directly enters the old age.

(When using CMS, the default new generation collector is ParNew) (Sometimes when the new generation GC needs to find the new generation objects referenced in the old generation, a technique called "card table" will be used at this time to avoid the old generation. I don’t know how to scan the whole table for the time being..., the card table is introduced: https://blog.csdn.net/z69183787/article/details/104939205 )

The meaning of Survivor area:

If there is no survivor, every time Eden performs minor gc, the surviving objects will enter the old age, and the old age will soon be filled and enter the major gc. Since the space in the old age is generally large, it takes much longer to perform a gc! In particular, frequent full GC will affect the response and connection of the program!

Survivor exists to reduce the objects sent to the old generation, thereby reducing the occurrence of Full gc. The default setting is that after 16 times the minor gc is still alive in the young generation before the objects will be sent to the old generation.

Why are there two Survivors:

 Mainly to solve the problem of memory fragmentation and efficiency . If there is only one Survivor, there will be data from Eden to Survivor every time a minor gc is triggered, and the cycle continues. Note that the Survivor area will also be garbage collected, which will cause memory fragmentation. As shown below:

    Fragmentation may lead to insufficient contiguous space in the heap to store a large object, affecting program performance. If there are two Survivors, the remaining objects can be concentrated on one Survivor to avoid fragmentation. As shown below:

The difference between Minor GC and Full GC and trigger conditions:

Minor GC:

  For the replication algorithm , when the young generation Eden area is full, a Minor GC will be triggered to copy the surviving objects of Eden and From Survivor to another piece of To Survivor.

    Note: If an object survives for more than a certain number of Minor gc times, it will directly enter the old age and will no longer be assigned to To Survivor (default 15 times, corresponding to the virtual machine parameter -XX:+MaxTenuringThreshold).

Full GC:

Used to clean up the entire heap space. Its trigger conditions are mainly as follows:

  1. Explicitly call System.gc method (JVM is recommended to trigger).
  2. Insufficient space in the method area (this will not happen in JDK8 and later, see below for details)
  3. Insufficient space in the old generation caused Full GC. This situation is more complicated, there are the following:
    1. Caused by large objects directly entering the old age, defined by the -XX:PretenureSizeThreshold parameter
    2. In Minor GC, objects that have experienced multiple Minor GC and still exist enter the old age. As mentioned above, it is defined by the -XX:MaxTenuringThreashold parameter
    3. In Minor GC, the dynamic object age determination mechanism will transfer the object to the old age in advance. The age is accumulated from young to old. When a certain age group is added, the accumulated sum exceeds the survivor area* -XX:TargetSurvivorRatio, the objects from this age group up to the old age
    4.  In Minor GC, when the Eden and From Space areas are copied to the To Space area, if the memory is larger than the available memory in the To Space area, the object will be directly transferred to the old generation

The JVM space allocation guarantee mechanism may trigger Full GC:

Before the Minor GC, the JVM space guarantee allocation mechanism may trigger 3.2, 3.3, and 3.4 to occur, that is, trigger a Full GC.

Space guarantee allocation means that before the occurrence of Minor GC, the virtual machine checks whether the largest available continuous space in the old generation is greater than the total space of all objects in the new generation.

If it is greater than, this Minor GC is safe.

If it is less, the virtual machine checks whether the HandlePromotionFailure setting value allows guarantee failure. If HandlePromotionFailure=true, then it will continue to check whether the maximum available continuous space in the old generation is greater than the average size of the objects promoted to the old generation. If it is greater than the average size of the objects promoted to the old generation, a Minor GC is attempted, but this time Minor GC is still risky and fails After that, Full gc will be initiated again; if it is less than or HandlePromotionFailure=false, then Full GC will be performed directly instead.

All will say that a Full GC is likely to be triggered by a Minor GC .

PS: Why does HotSpot cancel the permanent generation in JDK8

 JDK8 canceled the permanent generation and added a new area called Metaspace, which corresponds to the method area in the JVM specification (mainly storing some class and metadata information). The difference is that metaspace does not use memory in the JVM, but uses local memory.

The reasons for this are roughly as follows:

       1. Strings exist in the permanent generation, which is prone to performance problems and memory overflow.

  2. It is difficult to determine the size of the class and method information, so it is more difficult to specify the size of the permanent generation. Too small is prone to permanent generation overflow, and too large is likely to cause overflow of the old generation.

  3. The permanent generation will bring unnecessary complexity to the GC, and the recovery efficiency is low.

  4. Oracle may combine HotSpot and JRockit into one.

Supplement the JDK8 memory model diagram:

 

reference:

 

https://blog.csdn.net/antony9118/article/details/51425581 (the meaning of two Survivors)

https://zhidao.baidu.com/question/1111800566588999699.html (When is Full GC triggered)

https://blog.csdn.net/l1394049664/article/details/81486470#%E4%BA%94%E3%80%81java8%E5%86%85%E5%AD%98%E6%A8%A1%E5 %9E%8B%E5%9B%BE (JDK8 memory model diagram)

https://blog.csdn.net/quinnnorris/article/details/75040538 (Analysis of reachability analysis algorithm)

https://segmentfault.com/a/1190000007726689 (what is the card table)

Guess you like

Origin blog.csdn.net/z69183787/article/details/104938075