Drunk series: JVM garbage collection mechanism and memory allocation strategy of Drunk

Click on the blue font above and select "Star Official Account"

High-quality articles, delivered immediately

99 sets of Java enterprise-level actual combat projects

4000G Architect Information

Lead: The official account will launch a series of technical articles after drinking, all of which are dry goods, hope not to get drunk!

Before drinking, we should have an opening remark. I think everyone has read the previous article. It was our first time drinking. Those who want to review can continue to review it!

Next, let's have a good drink again, then the dishes to go with alcohol must be indispensable, and two side dishes will be served first.

1. Reference counting method????

Add a reference counter to the object. Whenever there is a reference to it, the counter value will be +1; when the reference is invalid, the counter value will be -1; any time an object with a counter of 0 can no longer be used.

2. Accessibility analysis and calculation????

Using a series of objects that become "GC Roots" as the starting point, starting from these nodes and searching downwards, the searched path is called the reference chain. When there is no reference chain from an object to GC Roots, it is proved that the object is unavailable.

Some drinkers may not understand, what is GC Roots, I will tell you if I drink one????

1. The object referenced in the virtual machine stack (local variable table in the stack frame) [object of new() in the method]

2. The object referenced by the class static property in the method area [static A a = new A()]

3. Objects referenced by constants in the method area

4. Objects referenced by JNI (in general, Native methods) in the native method stack

Come to a picture to let the drinkers understand better

Need a toast after eating????

3. Using the reachability analysis algorithm, is the object survived or destroyed????

Java uses the reachability analysis algorithm to determine whether the object is alive.

Objects that are not reachable in the reachability analysis algorithm are not "must be destroyed." At this time, they are in the "probation" stage. To truly announce the death of an object, they have to go through at least two marking processes: if the object does not have a reference chain connected to GC Roots after the reachability analysis, it will be the first time. Mark and perform a filter, the filter condition is whether it is necessary for this object to execute the finalize() method. When the object does not cover the finalize() method, or the finalize() method has been called by the virtual machine, the virtual machine regards both cases as "no need to execute". If it is necessary for this object to execute the finalize() method, then this object successfully saves itself when executing this method-as long as it re-establishes a relationship with any object in the reference chain, such as assigning itself to a class variable or The member variable of the object, it will not be recycled when it is marked the second time.

Garbage collection algorithm

One, mark-sweep algorithm???

The most basic collection algorithm, like its name, is divided into two stages: "marking" and "clearing": first, all objects that need to be recycled are marked, and all marked objects are uniformly recycled after the marking is completed. Its main shortcomings have bright spots: one is the efficiency problem, the efficiency of the two processes of marking and clearing is not high; the other is the space problem, after the mark is cleared, a large number of discontinuous memory fragments will be generated, and too much space fragmentation may cause later When a large object needs to be allocated during the running of the program, it cannot find enough contiguous memory and has to trigger another garbage collection in advance.

Second, the replication algorithm???

In order to solve the problem of efficiency, a collection algorithm called "copy" appeared, which divides the available memory into two equal-sized pieces, and only uses one of them at a time. When this block is used up, copy the surviving objects to another block, and then clean up the used memory space at once, so that the entire half area is reclaimed, and memory is not considered during memory allocation. For complex situations such as fragmentation, just move the pointer and allocate memory in order, which is simple to implement and efficient to run. It's just that the cost of this algorithm is to reduce the memory to half, which is too high.

Three, mark-sorting algorithm???

The marking process is still the same as the "mark-sweep" algorithm, but the subsequent steps are not to directly clean up recyclable objects, but to move all surviving objects to one end, and then directly clean up the memory outside the end boundary.

Fourth, the use of generational collection algorithm???

The current garbage collection of commercial virtual machines adopts the "generational collection" algorithm, which divides the memory into several blocks according to the life cycle of the object. Generally, the Java heap is divided into the new generation and the old generation, and the most appropriate collection algorithm is adopted according to the characteristics of each generation. In the new generation, a large number of objects are found to die each time a garbage collection, and only a few survive, then the replication algorithm is selected, and the collection can be completed by paying a small amount of the replication cost of the surviving objects. In the old age, because the object has a high survival rate and no extra space for its allocation guarantee, it must be recycled using the "mark-clean" or "mark-and-sort" algorithm.

Memory allocation strategy

In general, the memory allocation of objects is allocated on the heap. Objects are mainly allocated in the Eden area of ​​the young generation. In a few cases, they may be directly allocated in the old generation. The allocation rules are not 100% fixed. The details depend on which combination of garbage collectors are currently used, as well as the settings of memory-related parameters in the virtual machine.

1. The objects are allocated in the Eden area of ​​the new generation????

In most cases, objects are allocated in the Eden area of ​​the young generation. When the Eden area does not have enough space for allocation, the virtual machine will initiate a Minor GC. Use code to demonstrate to drinkers

/**
 * 对象优先在Eden 区分配
 *
 * 虚拟机参数设置:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails
 *  -verbose:gc 在控制台输出GC情况
 *  -Xms20M -Xmx20M -Xmn10M 限制Java堆大小为20MB,不可扩展,其中10MB分配给新生代,剩下10MB分给老年代
 *  -XX:+PrintGCDetails 收集器日志参数,告诉虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前的内存各区域分配情况
 * Created by lxs.
 * 2020/5/22 6:25 PM
 */
public class TestMinorGC {


    private static final int _1MB = 1024 * 1024;


    public static void main(String[] args) {
        byte[] obj1, obj2, obj3;


        obj1 = new byte[2 * _1MB];
        obj2 = new byte[2 * _1MB];
        obj3 = new byte[3 * _1MB];  // 发生Minor GC
    }


}

Run as shown in the figure below:

The first red box means that the result of this GC is that the Cenozoic 5650KB becomes 448KB

The total 5650KB in the second red box becomes 4544KB, which does not decrease much. That is because the two objects obj1 and obj2 are alive, and the virtual machine hardly finds objects that can be recycled.

The third red box represents the Eden area, Survivor from area and Survivor to area. The memory size ratio is 8:1:1, and the total is exactly 10MB.

The fourth red box is 10MB in the old age.

The reason for this GC is that when allocating memory for obj3, the Eden area has been occupied at least 4MB, and the remaining space is insufficient to allocate the 3MB memory required by obj3, so a Minor GC occurred. During the GC, the virtual machine found that all the existing two 2MB objects could not be placed in the Survivor space, so it had to transfer to the old age through the allocation guarantee mechanism in advance.

After the GC is over, the 3MB obj3 object is allocated in Eden, so the result of the program execution is that Eden occupies 3MB (obj3 occupied), Survivor is idle, and the old age is occupied 4MB (obj1, obj2). This can be proved by the GC log.

Second, the big object directly enters the old age????

/**
 * 大对象直接进入老年代
 *
 * 虚拟机参数设置:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:PretenureSizeThreshold=3145728
 *  -verbose:gc 在控制台输出GC情况
 *  -Xms20M -Xmx20M -Xmn10M 限制Java堆大小为20MB,不可扩展,其中10MB分配给新生代,剩下10MB分给老年代
 *  -XX:+PrintGCDetails 收集器日志参数,告诉虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前的内存各区域分配情况
 *  -XX:PretenureSizeThreshold=3145728 大于这个设置值的对象直接分配在老年代中,即大于3MB
 *  -XX:PretenureSizeThreshold 这个参数只对Serial和ParNew两款收集器有效,我的是用的Parallel Scavenge收集器,所以不顶用,我直接new了大一点的对象,7MB的直接分配到老年代了
 * Created by lxs.
 * 2020/5/22 6:25 PM
 */
public class TestBigObj {


    private static final int _1MB = 1024 * 1024;


    public static void main(String[] args) {
        byte[] obj;


        obj = new byte[7 * _1MB];
    }


}

Run as shown in the figure below:

In the above code, the created object is directly allocated to the old age. Look at the third red box, the obj object is 7MB, and the old age is 10MB, occupying 79%. But let’s look at the first two red boxes again. The Eden area does not allocate objects, but still occupies part of its memory. This is because when the virtual machine itself is loaded, it may have its own internal objects, so it occupies the memory. Say At this point, everyone should be able to understand the first piece of code. The three objects add up to 7MB. The Eden area should be able to fit. Of course not, plus the memory occupied by the virtual machine itself. Will trigger Minor GC.

Speaking of the last, let’s do one together. Before doing it, I want to say a few words. You often hear Minor GC, Major GC, and Full GC. What do these mean? In fact, it is the new generation GC, which is called Minor GC; Old generation GC, called Major GC; Full GC means that both the young generation and the old generation are recycled, okay, everyone, can you raise a glass????

There are hot recommendations???

The most popular Java database access framework (DAO layer)

What about those who want to replace C and Java now?

Why can single-threaded Redis achieve a million-level QPS?

Dry goods: A text to understand how client requests reach the server

Dry goods sharing : Scan the QR code to follow the public account below and reply to " 99 " in the background to receive 99 sets of actual combat projects + information

Charging want to focus on the process programmer flash charge treasure

If the article is helpful, read it and forward it.

Thank you for your support (*^__^*)

Guess you like

Origin blog.csdn.net/qq_17231297/article/details/106435892