JVM runtime data area-method area (evolution and garbage collection)

Method area evolution details and garbage collection

Method area evolution details

Permanent generation evolution process:

  1. First of all, it is clear: Only Hotspot has a permanent generation. For BEA JRockit, IBMJ9, etc., there is no concept of permanent generation. In principle, how to implement the method area belongs to the implementation details of the virtual machine, which is not governed by the "Java Virtual Machine Specification" and does not require uniformity.
  2. The changes in the method area in Hotspot are as follows:
    Insert picture description here
    JDK6: The method area is implemented by the permanent generation, using JVM virtual machine memory (virtual memory).
    Insert picture description here
    JDK7: The method area is implemented by the permanent generation and uses the JVM virtual machine memory.
    Insert picture description here
    JDK8: The method area is realized by the meta space, using the local memory of the physical machine.
    Insert picture description here

Why should the permanent generation be replaced by metaspace?

Official document: http://openjdk.java.net/jeps/122

  1. With the advent of Java 8, there will no longer be a permanent generation in the HotSpot VM. But this does not mean that the metadata information of the class has also disappeared. These data are moved to a local memory area not connected to the heap, this area is called the metaspace (Metaspace).
  2. Since the metadata of the class is allocated in the local memory, the maximum allocatable space of the metaspace is the available memory space of the system.
  3. This change is necessary for the following reasons:
  • It is difficult to determine the size of the space for the permanent generation. In some scenarios, if too many classes are dynamically loaded, OOM in the Perm area is likely to occur. For example, in an actual Web project, because there are many function points, many classes must be dynamically loaded during the running process, and fatal errors often occur. Such as: Exception in thread'dubbo client xx connector' java.lang .OutOfMemoryError: PermGen space, and the biggest difference between metaspace and permanent generation is that metaspace is not in the virtual machine, but uses local memory. Therefore, by default, the size of the metaspace is limited only by local memory.

  • Tuning the permanent generation is very difficult. The garbage collection in the method area mainly recycles two parts: the discarded constants in the constant pool and the no longer used types. The method area is tuned mainly to reduce the Full GC.

String constant pool

Why should the string constant pool StringTable be adjusted?

  • StringTable is placed in the heap space in JDK7. Because the collection efficiency of the permanent generation is very low, the garbage collection of the permanent generation will be executed during the Full GC, and the Full GC will only be triggered when the space of the old generation is insufficient and the permanent generation is insufficient;
  • This leads to StringTable recycling efficiency is not high, and a large number of strings will be created during development, recycling efficiency is low, resulting in insufficient permanent generation memory, put it in the heap, can reclaim the memory in time.

Where to put static variables

Where is the object entity?

/**
 * 结论:
 * 1、静态引用对应的对象实体(也就是这个new byte[1024 * 1024 * 100])始终都存在堆空间,
 * 2、只是那个变量(相当于下面的arr变量名)在 JDK6,JDK7,JDK8 存放位置中有所变化
 *
 * jdk7:
 * -Xms200m -Xmx200m -XX:PermSize=300m -XX:MaxPermSize=300m -XX:+PrintGCDetails
 * jdk 8:
 * -Xms200m -Xmx200m -XX:MetaspaceSize=300m -XX:MaxMetaspaceSize=300m -XX:+PrintGCDetails
 */
public class StaticFieldTest {
    
    
    private static byte[] arr = new byte[1024 * 1024 * 100];//100MB

    public static void main(String[] args) {
    
    
        System.out.println(StaticFieldTest.arr);
    }
}

Under JDK6 environment: Under
Insert picture description here
JDK7 environment:
Insert picture description here
Under JDK8 environment:
Insert picture description here
Where are the variables (names) stored?

Use JHSDB tools to analyze:

public class StaticObjTest {
    
    
    static class Test {
    
    
        static ObjectHolder staticObj = new ObjectHolder();
        ObjectHolder instanceObj = new ObjectHolder();

        void foo() {
    
    
            ObjectHolder localObj = new ObjectHolder();
            System.out.println("done");
        }
    }

    private static class ObjectHolder {
    
    
    }

    public static void main(String[] args) {
    
    
        Test test = new StaticObjTest.Test();
        test.foo();
    }
}

Under JDK6 environment:

  1. staticObj is stored in the method area along with the type information of Test;

  2. instanceObj is stored in the Java heap along with the object instance of Test;

  3. localObject (local variable) is stored in the local variable table of the stack frame of the foo() method;

  4. The test found that the addresses of the data of the three objects in the memory all fall within the range of the Eden area, so the conclusion: as long as the object instance is bound to be allocated in the Java heap.
    Insert picture description here

  1. 0x00007f32c7800000 (start address of Eden area) —- 0x00007f32c7b50000 (end address of Eden area),
  2. It can be found that the three variables are in this range,
  3. So the above conclusion can be obtained.
  1. Then, I found a place to refer to the staticObj object, which was in an instance of java.lang.Class, and gave the address of this instance. Checking the object instance through the Inspector, we can clearly see that this is indeed a java. An object instance of type lang.Class has an instance field named staticobj:
    Make
  • From the perspective of the conceptual model defined in the "Java Virtual Machine Specification", all Class-related information should be stored in the method area. However, the "Java Virtual Machine Specification" does not specify how to implement the method area. Become a thing that allows different virtual machines to flexibly control themselves. HotSpot virtual machines of JDK7 and later versions choose to store static variables and type mapping Class objects on the Java language side together, and store them in the Java heap, which is also clearly verified from experiments.

Garbage collection in method area

  1. Some people think that the method area (such as the metaspace or permanent generation in the Hotspot virtual machine) has no garbage collection behavior, but it is not. The "Java Virtual Machine Specification" has very loose constraints on the method area. It is mentioned that the virtual machine may not be required to implement garbage collection in the method area. In fact, there are indeed collectors that have not implemented or failed to fully implement method area type unloading (for example, the ZGC collector in the JDK11 period does not support class unloading).

  2. Generally speaking, the recovery effect in this area is difficult to be satisfactory, especially the type of unloading, the conditions are quite harsh. But sometimes the recycling of this part of the area is indeed necessary. In the previous bug list of Sun company, several serious bugs that have appeared are due to the low version of the HotSpot virtual machine not fully reclaiming this area and causing memory leaks.

  3. The garbage collection in the method area mainly recycles two parts: the discarded constants in the constant pool and the no longer used types.

    1. Let me talk about the two main types of constants mainly stored in the constant pool in the method area: literals and symbolic references. The literal is relatively close to the concept of constants at the Java language level, such as text strings, constant values ​​declared as final, and so on. Symbolic references belong to the concept of compilation principles, including the following three types of constants:

    • Fully qualified names of classes and interfaces
    • Field name and descriptor
    • Method name and descriptor

    2. The HotSpot virtual machine's recycling strategy for the constant pool is very clear, as long as the constants in the constant pool are not referenced anywhere, they can be recycled.

    3. Recycling discarded constants is very similar to recycling objects in the Java heap. (Regarding the recovery of constants is relatively simple, the focus is on the recovery of classes)

Class unloading in the method area:

  1. It is relatively simple to determine whether a constant is "deprecated", and the conditions for determining whether a type belongs to a "class no longer used" are more demanding. The following three conditions need to be met at the same time:

    • All instances of this class have been recycled, that is, there are no instances of this class and any derived subclasses in the Java heap;
    • The class loader that loaded the class has been recycled. This condition is usually difficult to achieve unless it is a carefully designed alternative class loader scenario, such as OSGi, JSP reloading, etc.;
    • The java.lang.Class object corresponding to this class is not referenced anywhere, and the methods of this class cannot be accessed anywhere through reflection.
  2. The Java virtual machine is allowed to recycle the useless classes that meet the above three conditions. What I am talking about here is only "allowed", not the same as an object. If there is no reference, it will inevitably be recycled. Regarding whether to recycle the type, the HotSpot virtual machine provides the -Xnoclassgc parameter to control. You can also use -verbose:class and -XX:+TraceClass-Loading, -XX: +TraceClassUnLoading to view class loading and unloading information.

  3. In scenarios where a large number of bytecode frameworks such as reflection, dynamic proxy, CGLib, etc. are used to dynamically generate JSP and OSGi and frequent custom class loaders, the Java virtual machine is usually required to have the ability to unload types to ensure that methods are not affected. The area causes excessive memory pressure.

Run-time data area summary

Insert picture description here

Common interview questions

  1. Baidu
  • Three sides: Tell me about the JVM memory model. What are the areas? What are they doing?
  1. Ant Financial:
  • Java8's memory generation improvement
  • Which areas are the JVM memory divided into, and what is the function of each area?
  • One side: JVM memory distribution/memory structure? The difference between stack and heap? The structure of the heap? Why two survivor areas?
  • Two sides: the proportional distribution of Eden and survior.
  1. Xiaomi:
  • JVM memory partition, why should there be a new generation and an old generation?
  1. Byte bounce:
  • Two sides: Java's memory partition
  • On the second side: talk about the vm runtime database area.
  • When will the subject enter the old age?
  1. Jingdong:
  • JVM memory structure, Eden and Survivor ratio.
  • Why should JVM memory be divided into the new generation, the old generation, and the persistent generation. Why is the new generation divided into Eden and survivor.
  1. Tmall:
  • One side: Jvm memory model and partition, you need to detail what to put in each area.
  • One side: What changes did Java 8 make to the JVM memory model?
  1. Pinduoduo:
  • Which areas are the JVM memory divided into, and what is the function of each area?
  1. Meituan:
  • java memory allocation
  • Will garbage collection occur in the permanent generation of jvm?
  • One side: JVM memory partition, why should there be a new generation and an old generation?

Guess you like

Origin blog.csdn.net/qq_33626996/article/details/114547495