1 Interaction between heap, stack and method area

The interaction between heap, stack, and method areas

2. Understanding of method area

  • The Java Virtual Machine specification makes it clear that although all method areas are logically part of the heap, some simple implementations may not choose to do garbage collection or compression. For HotSpot, there is also a method area called a non-heap to separate it from the Heap
  • The Method Area, like the Java heap, is an Area of memory shared by individual threads
  • The method area is created at JVM startup, and its actual physical memory space can be as discontinuous as the Java heap area
  • The size of the method area, like the heap space, can be fixed or expandable
  • The size of the method area determines how many classes the system can hold. If the system defines too many classes and causes the method area to overflow, the VIRTUAL machine will also throw an overflow error: Java. Lang. OutOfMemoryError: PermGen space or Java. Lang, OutOfMemoryError: Metaspace, such as:
    • Load a large number of third-party JAR packages;
    • Too many Tomcat projects are deployed.
    • A large number of dynamically generated reflection classes;
  • Shutting down the JVM frees up memory in this area

For example, use JVisualVM to view the number of loaded classes

public class MethodAreaDemo { public static void main(String[] args) { System.out.println("start..." ); try { Thread.sleep(1000000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end..." ); }}Copy the code

  • In JDK7 and before, it was customary to call a method area a permanent generation. Starting with JDK8, permanent generations are replaced with meta-spaces
  • In essence, method blocks and permanent generations are not equivalent. Only for hotSpot. The Java Virtual Machine Specification does not have uniform requirements on how to implement the method area. For example: BEA JRockit/IBM J9 does not have the concept of a permanent generation

  • In JDK8, the concept of permanent generations has finally been scrapped completely and replaced with Metaspace, which is implemented in local memory as in JRockit and J9
  • Similar in nature to permanent generations, meta-spaces are implementations of method areas in the JVM specification. However, the biggest difference between the meta-space and the permanent generation is that the meta-space is not in the memory set by the VM, but in the local memory
  • It’s not just the names of the permanent generations and metacases that have changed. The internal structure has also been adjusted
  • If the method area cannot meet the new memory allocation requirements, an OOM exception will be raised

3 Set the size to OOM

The size of the method area does not have to be fixed, and the JVM can adjust it dynamically based on the needs of the application

  • Before jdk7 and
    • A XX: PermSize is used to set the initial allocation of permanent generation space. The default value is 20.75 MB
    • -xx: MaxPermSize Sets the maximum space that can be allocated for the permanent generation. The default is 64M for 32-bit machines and 82M for 64-bit machine mode
    • When the number of classes loaded by the JVM exceeds this value, OutOfMemoryError: PermGen Space is raised
  • Jdk8 and later
    • The metadata area size can be specified using -xx: MetaspaceSize and -xx: MaxMetaspaceSize instead of the previous two parameters
    • The default values are platform dependent. On Windows, the value of -xx: MetaspaceSize is 21M, and the value of -xx: MaxMetaspaceSize is -1, indicating that there is no limit
    • Unlike the permanent generation, if the size is not specified, the virtual machine uses up all available system memory by default. If the metadata area overflows, the VM also throws OutOfMemoryError: Metaspace
    • The default initial metadata space for a 64-bit server JVM is 21M, which is the initial high water mark. Once this watermark is reached, FULLGC triggers and unloads unused classes, and the high watermark is reset. The value of the new high water level depends on how much space is freed after GC. If the free space is insufficient, increase the value appropriately without exceeding the maximum set point. If too much space is freed, lower this value appropriately
    • If the initial high water level is set too low, the above high water level adjustment will occur many times, and the fullGC will be called many times. To avoid frequent fullGCs, it is recommended to set -xx :MetaspaceSize to a relatively high value
* jdk8 and later: * JPS -> jinfo-flag PermSize [process id] * -xx :PermSize=100m -xx :MaxPermSize=100m * * jdk8 and later: JPS -> jinfo-flag MetaspaceSize [process ID] * -xx :MetaspaceSize=100m -xx :MaxMetaspaceSize=100mCopy the code

3.1 Method OOM

  • To resolve OOM or Heap space exceptions, a common method is to first analyze heap dump snapshots through a Memory image analysis tool (such as Eclipse Memory Analyzer). The focus is to determine whether the objects in Memory are necessary. In other words, it is important to know whether there is a Memory leak

(Memory 0verflow)

  • If it is a memory leak, you can further look at the leak object’s chain of references to GC Roots through the tool. You can then find out how the leaking objects are associated with GCRoots and cause the garbage collector to fail to reclaim them automatically. With the information of the type of the leaking object and the GC Roots reference chain, the location of the leaking code can be more accurately located
  • If there is no memory leaks, in other words, an in-memory object does also have to live with, it shall check the pile of parameters of the virtual machine (-xmx and – Xms), compared with the machine physical memory to see if can also big, check whether there is some objects from the code _ life cycle is too long, the state holding time is too long, Try to reduce the memory consumption of the program’s runtime
/** * jdk6/7中 : * -xx :PermSize=10m -xx :MaxPermSize=10m ** jdk8中 :  * -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m * */ public class OOMTest extends ClassLoader { public static void main(String[] args) { int j = 0; try { OOMTest test = new OOMTest(); for (int i = 0; i < 10000; I++) {// create a ClassWriter object, which is used to generate the binary bytecode ClassWriter ClassWriter = new ClassWriter(0); // Specify the version number, modifier, class name, package name, parent class, Visit (opcodes. V1_6, opcodes. ACC_PUBLIC, "Class" + I, NULL, "Java /lang/Object", null); Byte [] byte[] code = classwriter.tobytearray (); byte[] code = classwriter.tobytearray (); // Class load test.defineclass ("Class" + I, code, 0, code.length); / / Class object j++; } } finally { System.out.println(j); }}}Copy the code

4. Internal structure of method area

The method area stores type information that has been loaded by the virtual machine, constants, static variables, just-in-time compiler compiled code caches, and so on

4.1 Type Information

For each loaded type (class, interface, enum, annotation), the JVM must. The following types of information must be stored in the method area:

  • The full valid name for this type (full name = package name. The name of the class)
  • The full valid name of the type’s immediate parent (no parent for interface or java.lang. Object)
  • Modifiers of this type (some subset of public, abstract, final)
  • An ordered list of direct interfaces of this type

4.2 Domain Information (Member Variables)

  • The JVM must keep information about all fields of the type and the order in which the fields are declared in the method area
  • Domain information includes domain name, domain type, and domain modifiers (public, private, protected, static, final, volatile, transient).

4.3 Method Information

The JVM must hold the following information about all methods, including the declaration order, as well as domain information:

  • Method names
  • Method return type (or void)
  • Number and type of method parameters (in order)
  • Method modifiers (a subset of public, private, protected, static, final, synchronized, native, abstract)
  • Bytecodes, operand stack, local variable table and size of methods (except abstract and native methods)
  • Exception list (except for abstract and native methods)

The start and end location of each exception handler, the offset address of the code handler in the program counter, and the constant pool index of the caught exception class

4.4 Non-final class variables

  • Static variables are associated with the class and are loaded as the class is loaded; they become a logical part of the class data
  • A class variable is shared by all instances of the class, and you can access it even if there is no instance of the class
public class MethodAreaTest {
    public static void main(String[] args) {
        Order order = null;
        order.hello();
        System.out.println(order.count);
    }
}

class Order {
    public static int count = 1;
    public static final int number = 2;

    public static void hello() {
        System.out.println("hello!");
    }
}
Copy the code

4.5 Runtime constant pool

4.5.1 constant pool

  • A valid bytecode file contains not only the version information, fields, methods, and interface descriptions of the class, but also the Constant Pool Table, which contains various literals and symbolic references to type fields and methods
  • A Java source file of classes, interfaces, compiled to produce a bytecode file. In Java, bytecodes require data, and usually that data is too large to be stored directly in bytecodes, or another way, you can store it in a constant pool and the bytecodes contain references to the constant pool. Runtime constant pools are used for dynamic linking
  • What’s in the constant pool?
    • Number of values
    • A string value
    • Class reference
    • Field reference
    • Method references
  • A constant pool, which can be viewed as a table from which virtual machine instructions find the class names, method names, parameter types, literals, and so on to execute

4.5.2 Runtime constant pool

  • The Runtime Constant Pool is part of the method area
  • The constant pool table is the part of the class file that holds the various literal and symbolic references generated at compile time and is stored in the runtime constant pool in the method area after the class is loaded
  • Runtime constant pool, which is created after classes and interfaces are loaded into the VIRTUAL machine
  • The JVM maintains a constant pool for each loaded type (class or interface). Data items in a pool, like array items, are accessed by index
  • The runtime constant pool contains a variety of constants, from numeric literals that are explicit at compile time to method or field references that are not available until they are parsed at run time. Instead of a symbolic address in the constant pool, this is converted to a real address. Another important feature of run-time constant pools as opposed to Class file constant pools is that they are dynamic
  • When creating a runtime constant pool for a class or interface, the JVM throws an OutOfMemoryError if the amount of memory required to construct the runtime constant pool exceeds the maximum that can be provided by the method area
  • A run-time constant pool is similar to the Symbol table in traditional programming languages, but it contains a bit more data than the symbol table
  • When creating a runtime constant pool for a class or interface, the JVM throws an OutOfMemoryError if the amount of memory required to construct the runtime constant pool exceeds the maximum that can be provided by the method area

5 Example for using method area

public class MethodAreaDemo { public static void main(String[] args) { int x = 500; int y = 100; int a = x / y; int b = 50; System.out.println(a + b); }}Copy the code

Bytecode instruction

 0 sipush 500
 3 istore_1
 4 bipush 100
 6 istore_2
 7 iload_1
 8 iload_2
 9 idiv
10 istore_3
11 bipush 50
13 istore 4
15 getstatic #2 <java/lang/System.out>
18 iload_3
19 iload 4
21 iadd
22 invokevirtual #3 <java/io/PrintStream.println>
25 return
Copy the code

6 Evolution details of the method area

6.1 clear

To be clear: only HotSpot has persistent generation. For BEA JRockit, IBM J9, etc., there is no concept of permanent generation. In principle, how to implement the method area is a virtual machine implementation detail that is not governed by the Java Virtual Machine Specification and does not require unification

6.2 Method area changes in Hotspot

  • Jdk1.6 and earlier: Permanent generation, where static variables are stored
  • Jdk1.7: permanent generation exists, but has been “de-permanent”, string constant pool, static variables removed, stored in the heap
  • Jdk1.8 and later: No persistent generation, type information, fields, methods, constants are stored in local memory meta-space, but the string constant pool, static variables are still in the heap

6.3 Why should the method area (permanent generation) be replaced by the meta-space

  • With the advent of Java8, persistent generations are no longer seen in HotSpot VM. But that doesn’t mean classes. The metadata information of the. This data is moved to an area of local memory not connected to the heap, called Metaspace.
  • Since the metadata of a class is allocated in local memory, the maximum allocatable space of the metadata space is the memory space available to the system
  • This change was necessary for several reasons
    • Setting the size of the space for the permanent generation is difficult to determine.

In some scenarios, if there are too many dynamically loaded classes, O0M in the Perm area is easily generated. For example, in a practical Web project, because there are many function points, many classes need to be dynamically loaded during operation, and fatal errors often occur. “The Exception in the thread ‘dubbo client 7.0.x.x connector’ Java lang. OutOfMemoryError: PermGenspace” and the biggest difference between space and permanent generation is: The meta-space is not in the virtual machine, but uses local memory. Therefore, by default, the size of the meta-space is limited only by local memory

  • Tuning persistent generations is difficult

6.4 Why Should StringTable Be Adjusted

Jdk7 puts StringTable in the heap space. Because the collection efficiency of the permanent generation is low, it is triggered during full GC. Full GC is triggered when the old generation runs out of space and the permanent generation runs out. This results in inefficient StringTable recycling. However, in our development, a large number of strings will be created, and the recycling efficiency is low, resulting in insufficient memory of permanent generation. Put it in the heap, it can recycle memory in time

7 Method area garbage collection

7.1 an overview of the

Some people think method districts are garbage – free, but they are not. The Java VIRTUAL Machine specification is very lax about method areas, and mentions that you don’t need a VIRTUAL machine to implement garbage collection in method areas. In fact, there are collectors that do not implement or do not fully implement method area type offloading, such as JDK11 ZGc in general this area of collection is not satisfactory, especially for type offloading, the conditions are quite harsh. But recycling in this area is sometimes necessary. Several of the most serious bugs on Sun’s previous Bug list were memory leaks caused by earlier versions of the Hotspot VIRTUAL machine not fully reclaiming this area

7.2 Method area garbage collection

The method area garbage collection collects two main parts: obsolete constants in the constant pool and types that are no longer used

  • There are two main types of constants stored in the method area constant pool: literals and symbolic references. Literals are close to the Java language level concepts of constants, such as text strings, constant values declared final, and so on. Symbolic references, on the other hand, belong to compilation principles and include three types of constants

Fully qualified names of classes and interfaces. Field names and descriptors. Method names and descriptors

  • The HotSpot VIRTUAL machine has a very clear policy for reclaiming constants from the constant pool as long as they are not referenced anywhere
  • Recycling deprecated constants is very similar to recycling objects in the Java heap
  • It is relatively easy to determine whether a constant is “obsolete,” while the criteria for determining whether a type is “no longer in use” are more demanding. The following three conditions must be met simultaneously:
    • All instances of the class are already recycled, that is, there are no instances of the class or any of its derived children in the Java heap
    • The classloader that loaded the class has already been recycled, a condition that is usually difficult to achieve unless it is a carefully designed alternative classloader scenario, such as OSGi, JSP reloading, and so on
    • 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 (JVM) is allowed to recycle useless classes that meet the above three criteria, only “allowed”, not necessarily recycled as objects do when they are no longer referenced. The HotSpot virtual machine provides the -xnoclassGC parameter to control whether or not to reclaim the type. You can also use -verbose: class and -xx: + traceclass-loading, -xx: Traceclassclass load and unload information
  • In scenarios where bytecode frameworks such as reflection, dynamic proxies, and CGLib are used extensively, JSPS are dynamically generated, and custom class loaders such as oSGi are frequently used, the Ability of the Java VIRTUAL machine to type unload is often required to ensure that the method area is not overloaded with memory

8 summarizes

Question:

  • baidu

Three aspects: what are the areas of the JVM memory model? What are they?

  • Ant Financial:

How many partitions are there in the JVM memory, and what does each partition do? One side: JVM memory distribution/memory structure? What’s the difference between stack and heap? The structure of the heap? Why two survivor zones? Side TWO: Eden and Survior proportional allocation

  • Millet:

JVM memory partition, why have new generation and old generation

  • Bytedance:

When will objects become obsolete in the JVM runtime data repository?

  • Jingdong:

JVM memory structure, Eden and Survivor ratio Why the JVM memory is divided into new generation, old generation, persistent generation. Why are the new generation Eden and Survivor

  • Tmall:

One side: THE MEMORY model of the Jvm, what changes have been made to Java8

  • Spelling is great:

How many partitions are there in the JVM memory, and what does each partition do

  • Meituan:

Java memory allocation garbage collection will occur in the permanent generation of THE JVM


JVM full directory

Class loading mechanism 3. Runtime data area [PC register, vm stack, local method stack] 4. Runtime data area [heap] 5. Runtime data area [method area] 6. Temporary absence 7. Runtime data area [instantiated memory layout and access location of objects, direct memory] 8. String constant pool 10. Garbage collection [overview, related algorithms] 11. Garbage collection [related concepts] 12. Common OOM 14. JDK command line tools