JVM system learning path series demo code address: github.com/mtcarpenter…

The Method Area, like the Java heap, is an Area of memory shared by threads that stores data such as type information that has been loaded by the virtual machine, constants, static variables, and code caches compiled by the just-in-time compiler. Although the Java Virtual Machine Specification describes the method area as a logical part of the Heap, it has an alias called “non-heap” to distinguish it from the Java Heap.

directory

  • Stack, heap, method area interaction
  • Method area understanding
  • Set method area size to OOM
  • The internal structure of the method area
  • Example of using method area
  • The evolution details of the method area
  • Method area garbage collection

Stack, heap, method area interaction

The previous two sections covered stacks and heaps, and this section covers the methods area, which is also the last section in the run-time methods area. In terms of thread sharing or not ThreadLocal: How to ensure the safety of multiple threads in concurrent environment? Typical applications are database connection management and session management

Stack, heap, method area interaction

  • Person: Stored in a meta-space, also known as a method area
  • Person: Stored in a table of local variables in the Java stack
  • New Person() : Stored in the Java heap

Method area understanding

The method area is mainly stored inClass, and the heap mainly holds instantiated objects

  • Method AreaThe Java heapAgain, 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 scalable.
  • 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 spaceorjava.lang.OutOfMemoryError:Metaspace
    • Loaded a large number of third-party JAR packages, Tomcat deployed too many projects (30~50), a large number of dynamic generation of reflection classes
  • Shutting down the JVM frees up memory in this area.

Method area evolution in HotSpot

In JDK 7 and before, it was customary to refer to a method area as a permanent generation. Starting with JDK 8, permanent generations were replaced with meta-spaces.

  • After JDK 1.8, meta space is stored in off-heap memory

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: BEAJRockit/IBM J9 does not have the concept of a permanent generation.

  • Now, the use of permanent generation is not a good idea. Causes Java programs to be easier OOM (exceeding -xx :MaxPermsize limit)

However, in JDK8, the concept of permanent generation is completely abandoned and replaced by Metaspace, which is implemented in local memory like 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 uses local memory
  • It’s not just the names of the permanent generation and the metacolor that have changed
  • According to the Java Virtual Machine Specification, if the method area cannot meet the new memory allocation requirements, an OOM exception is raised

Set method area 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

  • through-xx:PermsizeTo set the initial allocation of the permanent generation. The default value is 20.75 MB
  • -XX:MaxPermsizeTo set the maximum allocatable space of the permanent generation. The default is 64M for 32-bit machines and 82M for 64-bit machine mode
  • When the JVM loads more class information than this value, an exception is reportedOutofMemoryError:PermGen space

After JDK8

  • Metadata area size can use parameters-XX:MetaspaceSize-XX:MaxMetaspaceSizeThe specified
  • The default values are platform dependent. Under Windows,-XX:MetaspaceSize21 m, –XX:MaxMetaspaceSizeThe value of is -1, that is, 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 will also throw an exceptionOutOfMemoryError:Metaspace
  • -XX:MetaspaceSize: Sets the initial size of the meta-space. The default for a 64-bit server-side JVM-xx:MetaspaceSizeThe value is 21 MB. This is the initial high watermark, and once it is reached, FullGC will be triggered to unload useless classes (i.e. their corresponding classloaders are no longer alive) and the high watermark will 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 this value appropriately until MaxMetaspaceSize is exceeded. If too much space is freed, lower this value appropriately.
  • If the initial high water mark is set too low, the above high water mark adjustment can occur many times. Multiple FullGC calls can be observed through the garbage collector logs. To avoid frequent GC, it is recommended that-XX:MetaspaceSizeSet to a relatively high value.

How to solve these OOM

  • To resolve OOM or heapSpace 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. If you have a Memory Leak or a Memory Overflow, you need to know the difference between a Leak and a Memory Overflow.
    • A memory leak is a problem where a large number of references point to objects that will not be used in the future, but will not be collected because they are associated with GC ROOT
  • 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 information of the GCRoots reference chain, the location of the leaking code can be more accurately located.
  • If there is no memory leak, in other words, objects in memory really must be alive, then the heap parameters of the virtual machine should be checked (-Xmx-Xms), compared with the physical memory of the machine to see if it can also be increased, check whether there is some object life cycle is too long, hold the state for too long from the code, try to reduce the memory consumption during the running period of the program.

The internal structure of the method area

The Method Area is used to store type information that has been loaded by the VIRTUAL machine, constants, static variables, and code cache compiled by the real-time compiler.

The type information

For each loaded type (class, interface, enum, annotation), the JVM must store the following type information 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

Filed information

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

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

Non-final class variable

  • 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 when there are no instances of the class
/** * non-final class variable */
public class MethodAreaTest {
    public static void main(String[] args) {
        Order order = newOrder(); order.hello(); System.out.println(order.count); }}class Order {
    public static int count = 1;
    public static final int number = 2;
    public static void hello(a) {
        System.out.println("hello!"); }}Copy the code

As shown in the code above, even if we set order to null, there is no null pointer exception

Global constants: static final

Global constants, which use static final to modify class variables declared as final, are handled differently; each global constant is assigned at compile time.

Runtime constant pool VS constant pool

Run time constant pool is run time constant pool.

  • Method area, which contains the run-time constant pool
  • A bytecode file that contains a constant pool
  • To understand the method area, you need to understand the ClassFile, because the information for loading classes is in the method area.
  • To understand the runtime constant pool in the method area, you need to understand the constant pool in classFile.

Constant pool

A valid bytecode file contains not only the class version information, fields, methods, and interface descriptors, but also the Constant Pool Table, which contains various literals and symbolic references to types, fields, and methods.

Why do WE need constant pools

A Java source file of classes, interfaces, compiled to produce a bytecode file. Bytecodes in Java require data support, usually too large to be stored directly in bytecodes, or, alternatively, in a constant pool, which contains references to the constant pool. Runtime constant pools are used for dynamic linking, as described earlier. For example:

public class SimpleClass {
    public void sayHello(a) {
        System.out.println("hello"); }}Copy the code

The above code is only 194 bytes long, but it uses structures like String, System, PrintStream, and Object. The amount of code here is actually very small, if there is more code, the reference structure will be more, and this is where the constant pool is needed.

What’s in the constant pool

  • Number of values
  • A string value
  • Class reference
  • Field reference
  • Method references

Take the following code for example

public class MethodAreaTest2 {
    public static void main(String args[]) {
        Object obj = newObject(); }}Copy the code

Will be translated into the following bytecode

new #2  
dup
invokespecial
Copy the code

summary

A constant pool can be thought of as a table from which virtual machine instructions find the class names, method names, parameter types, literals, and so on to execute. **

Run-time constant pool

  • Runtime Constant PoolIs part of the methods area.
  • Constant Pool TableIs the part of the Class file that holds various literals 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. So instead of having a symbolic address in the constant pool, we have a real address.
    • Another important feature of run-time constant pools as opposed to Class file constant pools is that they are dynamic.
      • string.intern()
  • 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.

Example of using method area

Use the following examples to illustrate the 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

Display of bytecode execution processThe operand 500 is first placed on the operand stackIt is then stored in the local variable table

Then repeat, put 100 into the local variable scale, and finally remove 500 and 100 from the variable scale to operate

Divide 500 and 100 and push the result

At the end is the output stream, which calls constants from the runtime constant pool

Finally call Invokevirtual (virtual method call) and return

return

The program counter always counts where the current code is running, so that it can be returned to normal after a method call, or to the original code for execution after a CPU switch.

The evolution details of the method area

To be clear: only Hotspot has persistent generation. For BEA JRockit, IBMJ9, 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 uniform method area changes in Hotspot.

JDK1.6 and before There are permanent generations, where static variables are stored
JDK1.7 There are permanent generations, but have been progressively “de-permanent”, string constant pools, static variables removed, and stored in the heap
JDK1.8 No persistent generation, type information, fields, methods, and constants are stored in the local memory meta-space, but the string constant pool, static variables are still in the heap.

When JDK6 has

Why should permanent generation be replaced by metaspace? **

JRockit is a fusion with HotSpot, because JRockit doesn’t have persistent generation, so they don’t need to configure persistent generation

  • With the advent of Java8, persistent generations are no longer seen in HotSpot VM. But this does not mean that the metadata information of the class has disappeared. 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 amount of space that can be allocated is the system’s available memory, this change is necessary for the following reasons:
    • Setting the size of the space for the permanent generation is difficult to determine.

In some scenarios, if too many classes are dynamically loaded, oom in the Perm area may be 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: PermGen space” 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.
    • This is mainly to reduce the Full GC

Some people think that method areas (such as meta-spaces or persistent generations in the HotSpot VIRTUAL machine) have no garbage collection behavior, but this is not true. The Java Virtual Machine Specification is very relaxed about method areas, mentioning that virtual machines are not required to implement garbage collection in method areas. In fact, collectors do exist that do not implement or fully implement method area type offloading (for example, the ZGC collector of the JDK11 era did not support class offloading). Generally speaking, the recovery effect of this area is not satisfactory, especially for the type of unloading, the conditions are quite harsh. But recycling in this area is sometimes necessary. Some of the most serious bugs on Sun’s previous Bug list were memory leaks caused by the fact that earlier versions of the HotSpot VIRTUAL machine did not fully reclaim this area. The garbage collection of the method area mainly collects two parts: discarded constants in the constant pool and unused types.

Why does StringTable reposition

Jdk7 puts StringTable in the heap space. Because the collection efficiency of the permanent generation is low, it is triggered during full GC. Fullgc is triggered when there is not enough space in the old age or when there is not enough permanent generation. 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.

Method area garbage collection

Some people think that method areas (such as meta-spaces or persistent generations in the Hotspot VIRTUAL machine) have no garbage collection behavior, but this is not true. The Java Virtual Machine Specification is very relaxed about method areas, mentioning that virtual machines are not required to implement garbage collection in method areas. In fact, collectors do exist that do not implement or fully implement method area type offloading (for example, the ZGC collector of the JDK11 era did not support class offloading). Generally speaking, the recovery effect of this area is not satisfactory, especially for the type of unloading, 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. The method area garbage collection collects two main parts: obsolete constants in the constant pool and types that are no longer used. Let’s start with the 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, are concepts related to compilation principles and include the following three constants:

  • Fully qualified names of classes and interfaces
  • The name and descriptor of the field
  • The name and descriptor of the method

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. (The collection of constants is relatively simple, focusing on the collection of classes)

  • 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, which can also be used-verbose:class As well as-xx: + traceclassloading, -xx: + traceclassclassView class loading and unloading 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.


Welcome to pay attention to the public number Shanma carpenter, I am Xiao Chun brother, engaged in Java back-end development, will be a little front-end, through the continuous output of a series of technical articles to literary friends, if this article can help you, welcome everyone to pay attention to, like, share support, we see you next period!