Garbage collection case - GC analysis

GC analysis

First run an empty code and set the virtual machine parameters: "-Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc".


public class Demo {

    private static final int _512KB = 512*1024;
    private static final int _1MB = 1024*1024;
    private static final int _6MB = 6*1024*1024;
    private static final int _7MB = 7*1024*1024;
    private static final int _8MB = 8*1024*1024;

    // -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc
    // -Xms20M -Xmx20M (初始和最大的堆空间20M)
    // -Xmn10M (新生代10M)
    // -XX:+UseSerialGC(垃圾回收器)
    // -XX:+PrintGCDetails -verbose:gc(打印GC的详情)
    public static void main(String[] args) {

    }

}

The result of the above operation is:

Heap space without any code logic

 It can be seen from the figure above that the heap is mainly divided into new generation (new generation), tenured generation (old generation), and Metaspace (metaspace).

For the new generation, we allocated 10M to the new generation in the JVM parameters, but the total of the new generation in the above figure is only 9216K, which is 1024K less, because the space in the default survival area To cannot be used, so the space of the new generation is 9216K. Eden space occupies 8M. Although we don't have any logic, 26% of the memory in Eden has been used at this time, because some objects are loaded by default when the program is running, and these objects are placed in Eden.

So what happens if we put a 7M object into the heap memory?

It can be seen from the figure that when a 7M object is inserted, a garbage collection is performed, and it is a Minor GC (if it is a Full GC, it will output a Full GC). The information DefNew in the garbage collection indicates that this is in the new generation For garbage collection, 2004K->600K (9216K) means that the occupied area before recycling is 2004K, after recycling, the memory occupies 600K and the total memory size is 9216K, and it takes 0.0333417 seconds. The information after this is an information of the entire heap memory, and the previous one is about the new generation. The heap memory takes up 2004K during recycling, and the 600K whole heap memory after recycling occupies a total of 19456K. The total recovery time of the heap memory takes 0.0386088 seconds.

Below the output information is the various information of the new generation and the old generation in the heap memory. It can be seen that the From area occupies 58% of the space, although the to area occupies 0%, but in the process of recycling, the To area is placed first and then the From and To areas are exchanged.

What if we are adding two 521KB objects in the above code?

Add the first 512KB object
Add a second 512KB object

 

 


 

 

 

 

 

 

 It can be clearly seen that when the first 512KB object was added, the space in Eden was relatively sufficient, but 96% of it was used after the addition, and only one GC was executed during the addition process. When adding the second 512KB object, the space in Eden is obviously not enough, so a garbage collection is performed again. Obviously, even if the new generation is recycled this time, the space requirement cannot be met, so many objects have been promoted to Although the old generation does not exceed the threshold, it is because the memory is very tight at this time.

GC Large Objects

When putting an object into the heap memory, if the placed object exceeds the size of the Garden of Eden, how should the JVM handle it at this time?

Because when we set the virtual machine parameters, we have set the size of Eden to be 8M. If an object of 8M is inserted at this time, the entire area of ​​Eden, that is, the new generation, will not be able to fit this object. No less than this 8M object. At this time, if there is enough space in the old generation, the large object will be directly promoted to the old generation, and garbage collection will not be triggered in this case.

If you insert two 8M objects, it is obvious that the heap space is insufficient at this time, so an error will be reported, but before the error is reported, the JVM will still save and perform Full GC, and Full Gc will trigger Minor GC.

When the memory overflow is placed in a child thread, it will not cause the execution exception of the Java main thread.

 

Guess you like

Origin blog.csdn.net/qq_35363507/article/details/104934530