[JVM] Nine, method area

Hello, everyone, I am a pig who is dominated by cabbage.

A person who loves to study, sleepless and forgets to eat, is obsessed with the girl's chic, calm and indifferent coding handsome boy.

If you like my text, please follow the public account "Let go of this cabbage and let me come"

09-Method area

1. Interaction between stack, heap, and method area

From the perspective of thread sharing or not

Insert picture description here

Through a simple example, we can clearly see the relationship between them.

Person person = new Person()

As long as the things coming out of new are placed in the Java heap, the class template is placed in the method area.

Insert picture description here

Second, the understanding of the method area

Where is the method area

The "Java Virtual Machine Specification" clearly states: "Although all method areas are logically part of the heap, some simple implementations may not choose to perform garbage collection or compression." But for HotSpotJVM, the method The area also has an alias called Non-Heap (non-heap), the purpose is to separate from the pair.

Therefore, the method area is regarded as a memory space independent of the Java heap.

Basic understanding of method area

  • The Method Area, like the Java heap, is a memory area shared by all threads.
  • The method area is created when the JVM starts, and its actual physical memory space can be discontinuous like the Java heap area.
  • The size of the method area, the same as the heap space, can be fixed or expandable.
  • The size of the method area determines how many classes the system can save. If the system defines too many classes and the method area overflows, the virtual machine will also exclude memory overflow errors: java.lang.OutOfMemoryError: PermGen space or java.lang.OutOfMemoryError : Metaspace
    • Load a large number of third-party jar packages; Tomcat has too many projects deployed (30-50), and a large number of dynamic reflection classes are generated
  • Closing the JVM will release the memory in this area.

The evolution of the method area in HotSpot

  • In jdk7 and before, it is customary to call the method area the permanent generation. Starting with jdk8, the permanent generation is replaced by metaspace.
  • In essence, the method area and the permanent generation are not equivalent. Only for hotspot. The "Java Virtual Machine Specification" does not make uniform requirements on how to implement the method area. For example: There is no concept of permanent generation in BEA JRockit/IBM J9.
    • Looking at it now, using the permanent generation back then was not a good idea. Make Java programs easier to OOM (exceed -XX: MaxPermSize upper limit)

Insert picture description here

  • In JDK 8, the concept of permanent generation was finally completely abandoned and replaced with Metaspace, which is implemented in local memory like JRockit and J9.
  • The nature of the metaspace is similar to that of the permanent generation, which is the realization of the method area in the JVM specification. However, the biggest difference between metaspace and permanent generation is that metaspace is not in the memory set by the virtual machine, but uses local memory.
  • Both the permanent generation and the metaspace have not only changed their names, but also adjusted their internal structure.
  • According to the "Java Virtual Machine Specification", if the method area cannot meet the new memory allocation requirements, an OOM exception will be thrown.

3. Setting method area size and OOM

Set the size of the method area memory

  • The size of the method area does not need to be fixed, the jvm can be dynamically adjusted according to the needs of the application.

  • jdk7 and before:

    • Use -XX: PermSize to set the initial allocation space of the permanent generation. The default value is 20.75M
    • -XX:MaxPermSize to set the maximum allocable space of the permanent generation. The default is 64M for 32-bit machines, and 82M for 64-bit machines
    • When the capacity of the class information loaded by the JVM exceeds this value, an exception OutOfMemoryError: PermGen space will be reported.
  • jdk 8 and later:

    • The size of the metadata area can be specified with the parameters -XX:MetaspaceSize and -XX:MaxMetaspaceSize, instead of the two original parameters mentioned above.
    • The default value depends on the platform. Under windows, -XX: MetaspaceSize is 21M, -XX: MaxMetaspaceSize is -1, that is, there is no limit.
    • Unlike the permanent generation, if you do not specify the size, by default, the virtual machine uses up all available system memory. If the metadata area method overflows, the virtual machine will also throw an exception OutOfMemoryError: Metaspace.
    • -XX: MetaspaceSize: Set the initial metaspace size. For a 64-bit server-side JVM, the default -XX: MetaspaceSize value is 21MB. This is the initial high water mark. Once this water mark is touched, Full GC will be triggered and unload useless classes (that is, the class loader corresponding to these classes no longer survives), and then this high water mark will be reset. The value of the new high water mark depends on how much space is released after GC. If the released space is insufficient, increase the value appropriately when it does not exceed MaxMetaspaceSize. If the free space is too much, lower the value appropriately.
    • If the initialized high-water mark is set too low, the above-mentioned high-water mark adjustment will happen many times. Through the log of the garbage collector, it can be observed that Full GC is called multiple times. In order to avoid frequent GC, it is recommended to set -XX: MetaspaceSize to a relatively high value.

    If you solve these OOM

    1. To solve OOM exceptions or heap space exceptions, the general method is to first analyze the heap dump snapshots from the dump through a memory image analysis tool (such as Eclipse Memory Analyzer), and the focus is to confirm whether the objects in the memory are necessary. , That is, we must first distinguish whether there is a memory leak (Memory Leak) or a memory overflow (Memory Overflow).

    2. If it is a memory leak, you can check the reference chain of the leaked object to GC Roots through the tool in one step. Then you can find out how the leaked objects are related to GC Roots and cause the garbage collector to be unable to automatically collect them. Knowing the type information of the leaked object and the information of the GC Roots reference chain, you can locate the location of the leaked code more accurately.

    3. If there is no memory leak, in other words all objects in the memory must still be alive, then the heap parameters of the virtual machine (-Xmx and -Xms) should be checked and compared with the physical memory of the machine to see if it can be adjusted. Large, check from the code whether there is a situation where some objects have a long life cycle and hold a state for too long, and try to reduce the memory consumption during the program runtime.

    Note: Use the tool to grab a snapshot to see if it is a memory overflow or a memory leak. For a memory leak, use the tool to further check the GC Roots reference chain and master the type information of the leaked object to locate the leaked code. If the memory overflows, adjust the parameters to see if there is an object with a long life cycle.

Fourth, the internal structure of the method area

Insert picture description here

What is stored in the method area

The description of the storage content of the method area in the book "In-depth understanding of the Java virtual machine" is as follows:

It is used to store type information, constants, static variables, and code cache compiled by the just-in-time compiler that have been loaded by the virtual machine.

[External link image transfer failed. The source site may have an anti-hotlinking mechanism. It is recommended to save the image and upload it directly (img-ajiVpbkn-1610109790715) (E:\2020 Winter Vacation Study Plan\Study Notes\JVM\images\Chapter 09_ Method area storage information.jpg)]

Internal structure of method area

Type information

For each loaded type (class class, interface interface, enumeration enum, annotation annotation), the JVM must store the following type information in the method area:

  1. The complete and valid name of this type (full name = package name. class name)
  2. The complete and effective name of the direct parent of this type (for interface or java.lang.Object, there is no parent)
  3. Modifiers of this type (public, abstract, a certain subset of final)
  4. An ordered list of direct interfaces of this type

Field information

  • The JVM must store all the field-related information of the type and the declaration order of the fields in the method area.
  • The relevant information of the domain includes: domain name, domain type, domain modifier (a subset of public, private, protected, static, final, volatile, transient)

Method information

The JVM must save the following information of all methods, including the order of declarations like the domain information:

  • Method name
  • The return type of the method (or void)
  • Number and types of method parameters (in order)
  • Method modifiers (a subset of public, private, protected, static, final, synchronized, native, abstract)
  • Method bytecodes, operand stack, local variable table and size (except abstract and native methods)
  • Exception table (except for abstract and native methods)
    • The start position and end position of each exception processing, the offset address of the code processing in the program counter, and the constant pool index of the caught exception class

non-final class variables

  • Static variables and classes are associated with each other. They are loaded as the class is loaded, and they become a logical part of the class data.
  • Class variables are shared by all instances of the class, and you can access it even when there is no class instance.

Supplementary note: global constant: static final

The processing method for class variables declared as final is different. Each global constant is allocated at compile time. For those without final modification, prepare is assigned a value of zero during connection and assigned during initialization.

Runtime constant pool vs constant pool

  • Method area, which contains runtime constant pool
  • Bytecode file, which contains constant pool
  • To figure out the method area, you need to understand ClassFile, because the information of the loaded class is in the method area.
  • To figure out the runtime constant pool of the method area, you need to understand the constant pool in ClassFile.

In addition to the description information of the class version information, fields, methods, and interfaces, a valid bytecode file also contains a piece of information that is a constant pool table (Constant Pool Table), which contains various literals and pairs of type fields And symbolic references to methods.

Why do you need a constant pool

Classes and interfaces in a java source file are compiled to generate a bytecode file. The bytecode in Java requires data support. Usually this kind of data is too large to be stored directly in the bytecode. In another way, it can be stored in the constant pool. This bytecode contains pointers to the constant pool. Reference. The runtime constant pool is used during dynamic linking, which was introduced before.

For example, although the following code is only 194 bytes, it uses structures such as String, System, PrintStream, and Object. The amount of code here is actually very small. If there is more code, more structures will be referenced, and a constant pool is needed here.

What's in the constant pool

Several data types stored in the constant pool include: quantity value, string value, class reference, field reference, method reference.

summary:

The constant pool can be regarded as a table. The virtual machine instructions find the type of class name, method name, parameter type, literal value, etc. to be executed according to this constant table.

Runtime constant pool

  • Runtime Constant Pool is part of the method area.
  • The Constant Pool Table is a part of the Class file, which is used to store various literals and symbol references generated by the compiler. This part of the content will be stored in the runtime constant pool of the method area after the class is loaded.
  • Runtime constant pool, after loading the class and interface to the virtual machine, the corresponding runtime constant pool will be created.
  • The JVM maintains a constant pool for each loaded type (class or interface). The data items in the pool are like array items and are accessed by index.
  • The runtime constant pool contains a variety of different constants, including numerical literals that are already clear at compile time, and method or field references can only be obtained after runtime parsing. At this time, it is no longer the symbolic address in the constant pool, and replaced with the real address here.
    • The runtime constant pool, compared to the class file constant pool, is another important feature: dynamic.
      • String.intern()
  • The runtime constant pool is similar to the symbol table in traditional programming languages, but the data it contains is enriched by the symbol table.
  • When creating the runtime constant pool of a class or interface, if the memory space required to construct the runtime constant pool exceeds the maximum value that the method area can provide, the JVM will throw an OutOfMemoryError exception.

5. Examples of the use of the method area

Six, the evolution details of the method area

  • First of all, it is clear: Only HotSpot has a permanent generation. For BEA JRockit, IBM J9, etc., there is no concept of permanent generation. In principle, if the implementation method area belongs to the implementation details of the virtual machine, it is not governed by the "Java Virtual Machine Specification" and does not require uniformity.
  • Changes in the method area in HotSpot:
jdk1.6 and before There is a permanent generation, and static variables are stored on the permanent generation
jdk1.7 There is a permanent generation, but it has been gradually "going to the permanent generation". The string constant pool and static variables are removed and stored in the heap
jdk1.8 and later No permanent generation, type information, fields, methods, and constants are stored in the meta space of local memory, but the string constant pool and static variables are still in the heap

Insert picture description here

Why the permanent generation should be replaced by metaspace

The "Java Virtual Machine Specification" says why it is necessary to replace it, because JRockit does not have a permanent generation, so the permanent generation is replaced. This is like asking why you have to line up, and then you say that I see others line up and I also line up, so why are others Are you in line?

  • 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).
  • 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.
  • 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. 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.

Why should String Table be adjusted

Put StringTable in the heap space in jdk7. Because the collection efficiency of the permanent generation is very low, it will only be triggered during full GC. And full gc is triggered only when there is insufficient space in the old generation and insufficient permanent generation. This results in StringTable recycling efficiency is not high. In our development, a large number of strings will be created, and the recycling efficiency is low, resulting in insufficient permanent generation memory. Put it in the pile, even if the memory is reclaimed.

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. The HotSpot virtual machine of JDK 7 and later versions chooses to store static variables and the mapped Class object of the type at the Java language side together, and store them in the Java heap. This is clearly verified from our experiments.

7. Garbage collection in the method area

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 do exist collectors that have not implemented or failed to fully implement method area type offloading (for example, the ZGC collector in the JDK 11 period does not support cumulative offloading).

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 Sun company's bug list, several serious bugs that have appeared are due to the low version of the HotSpot virtual machine that did not fully reclaim this area, which led to memory leaks.

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

  • Let me first talk about the two main types of constants stored in the constant pool in the method area: literals and symbol references. Literals are relatively close to the constant concepts of the Java language level, such as text strings, constant values ​​declared as final, and so on. The symbolic reference belongs to the concept of the compilation principle method, including the following three types of constants:
    • Fully qualified names of classes and interfaces
    • Field name and descriptor
    • Method name and descriptor
  • 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.
  • Recycling obsolete constants is very similar to reclaiming objects in the Java heap.

But it’s difficult to judge if it’s not cited

  • It is relatively simple to determine whether a constant is "deprecated", and the condition to determine whether a type belongs to a "class no longer used" is 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 and JSP reloading.
    • 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.
  • The Java virtual machine is allowed to recycle useless classes that meet the above three conditions. What I say here is only "allowed", not the same as an object. If there is no reference, it will be reclaimed. Regarding whether to recycle the type, the HotSpot virtual machine provides the -Xnoclassgc parameter to control, and you can also use -verbose:class and -XX:+TraceClass-Loading, -XX:TraceClassUnloading to view class loading and unloading information
  • In a large number of scenarios that use reflection, dynamic proxy, CGLib and other bytecode frameworks to dynamically generate JSP and OSGi frequently custom class loaders, it is usually necessary for the Java virtual machine to have the ability to type unload to ensure that there will be no errors. The method area causes excessive memory pressure.

8. Summary

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_44226263/article/details/112383599