1.JVM memory area

1.1 Program counter

A program counter is a small memory space that can be viewed as a line number indicator of the bytecode being executed by the current thread. In virtual machines, bytecode interpreters work by changing the counter value to select the next instruction to be executed. Branches, loops, jumps, exception handling, thread recovery and other basic functions depend on this counter. At any one time, a processor (kernel) executes instructions in only one thread. In order to restore the thread to the correct execution position after switching, each thread needs to have an independent program counter. Counters between threads do not affect each other and are stored independently. This kind of memory area is the thread’s private memory. This memory region is the only one where the Java Virtual Machine specification does not specify any OutOfMemoryError cases.

1.2 Java Virtual Machine Stack

The Java virtual machine stack is also thread-private and has the same life cycle as a thread. Each method creates a stack frame as it executes, which stores information about local variables, operand stacks, dynamic links, method exits, and so on. A method from the call to the completion of execution corresponds to a stack frame in the virtual machine stack to the process of the stack. The local variable table in the virtual stack holds various basic data types known at compile time (Boolean, byte, CHAR, short, int, float, long, double), object references (reference types), The returnAddress type refers to the address of a bytecode instruction. StackOverflowError: The stack depth of the thread request is greater than the depth allowed by the vm. OutOfMemoryError: The vm stack can be dynamically extended and cannot allocate enough memory.

1.3 Local method stack

The function of the Native method stack is similar to that of the virtual machine stack, except that the virtual machine stack performs Java method (that is, bytecode) services for the virtual machine, while the Native method stack serves the Native methods used by the virtual machine. Some virtual machines, such as the Sun HotSpot VIRTUAL machine, simply combine the local method stack with the virtual machine stack.

1.4 Java heap

The Java Heap is the largest chunk of memory managed by the Java virtual machine. The Java heap is an area of memory that is shared by all threads and is created when the virtual machine is started. The only purpose of the heap is to hold object instances, and almost all object instances are allocated here. The Java heap is the primary area managed by the garbage collector and is often referred to as the “GC heap”. From the point of view of memory collection, the Java heap can be subdivided into: new generation and old generation; More detailed are Eden space, From Survivor space, To Survivor space, etc. OutOfMemoryError: There is no memory in the heap to complete instance allocation, and the heap cannot be extended.

1.5 method area

The Method Area, like the Java heap, is an Area of memory shared by threads that stores information about classes loaded by the virtual machine, constants, static variables, code compiled by the just-in-time compiler, and so on. On the Hotspot VIRTUAL machine, many people prefer to refer to the method area as “persistent generation.” The method area, like the Java heap, does not require continuous memory and can choose to be fixed size or extensible, and optionally does not implement garbage collection. Garbage collection is relatively rare in this area, but it is not as “permanent” as the name of the permanent generation that data enters the method area. The main targets of this area are constant pool reclamation and type offloading.

1.5.1 Differences in method areas in JDK6-8

Prior to JDK7, the HotSpot VIRTUAL machine extended GC generation collection to the method area, using persistent generation to implement the method area. Memory reclamation in this area was targeted primarily for constant pool reclamation and offloading of types, but later HotSpot VIRTUAL machine implementations began to remove the method area from the persistent generation. Runtime constant pools have been removed from the permanent generation in JDK7, creating an area in the Java Heap for runtime constant pools. In JDK8, however, permanent generation is completely eliminated and the method area is placed directly in a local memory area not connected to the heap, called the meta-space.

Metaspace, similar in nature to the permanent generation, is an implementation of the method area in the JVM specification. However, the biggest difference between a meta-space and a permanent generation is that 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, but you can specify the size of the meta-space with parameters.

1.6 Runtime constant pool

The Runtime Constant Pool is part of the method area. In addition to the field, version, and other information described in the Class file, there is also a constant pool, which is used to store various literals and symbolic references generated at compile time. This part of the constant pool will be stored in the runtime constant pool when the Class is loaded into the method area.

2. HotSpot VIRTUAL machine object exploration

2.1 Object Creation

  1. When the virtual machine reaches a new instruction, it first checks to see if the instruction’s arguments locate a symbolic reference to a class in the constant pool, and to see if the class represented by the symbolic reference has been loaded, parsed, and initialized. If not, the corresponding class loading process must be performed first,
  2. The virtual machine will then allocate memory for the new objects, and the size of the memory required by the objects can be fully determined after the class is loaded. Object memory allocation can be divided into two kinds: pointer collision: set in the Java heap memory is absolutely neat, all used memory aside and free memory on the other side, there is a middle pointer as a cut-off point indicator, the allocated memory is just put the pointer to the free space there move a and the object is equal to the size of the distance. Free list: If memory in the Java heap is not neat, used memory and free memory cross each other, that is simply no way pointer collision, the virtual machine, you must maintain a list of records on which memory blocks are available, at the time of distribution from the list to find a large enough space division to the object instance, and update the list of records.

The choice of allocation method depends on whether the Java heap is clean, which in turn depends on whether the garbage collector used has collation capabilities.

Object creation is a very frequent activity in virtual machines and is not thread-safe in the case of concurrency. There are two ways to solve this problem: one is to synchronize the memory allocation action — in fact, the VIRTUAL machine uses CAS and retry to ensure atomization of the update operation. The other way is to allocate memory in different Spaces according to threads. Each Thread allocates a small chunk of memory in the Java heap, called Thread Local Allocation Buffer (TLAB). 3. The virtual machine then performs the necessary Settings on the object, such as the hash code of the object and the generational age of the GC, which are stored in the object header of the object. 4. When the above steps are complete, a new object has been created from the perspective of the virtual machine, but from the perspective of the Java program, the object has just started and the —-init method has not been executed. The new instruction is followed by the init method, which initializes the object as desired by the programmer, so that a usable object is fully generated.

2.2 Memory Layout of objects

In the HotSpot virtual machine, the layout of objects stored in memory can be divided into three areas: object headers, Instance Data, and alignment Padding.

2.2.1 object head

The object header contains two parts of information. The first part is used to store the runtime data of the object itself, and the lock status flag. The other part is a type pointer, which is a pointer to an object’s class metadata that the virtual machine uses to determine which class the object is an instance of.

2.2.2 Instance Data

The instance data portion is the valid information that the object actually stores, as well as the content of various types of fields defined in program code. Both inherited from a parent class and defined in a subclass need to be logged.

2.2.3 Align padding

Alignment padding doesn’t have to exist, it just acts as a placeholder. Since HotSpot VM’s automatic memory management system requires that the object’s starting address be an integer multiple of 8 bytes, that is, the object’s size must be an integer multiple of 8 bytes, which is made up by object padding.

2.3 Object Access positioning

Our Java program needs reference data on the stack to manipulate concrete objects on the heap. Since the Java Virtual Machine specification only specifies a reference to an object, it does not define how the reference should locate and access the object in the heap, so object access is implementation-dependent. At present, there are two main access methods: handle and direct pointer.

2.3.1 Handle Access

With handle access, the Java heap will be divided into a chunk of memory as a handle pool. Reference stores the handle address of the object, and the handle contains the specific address information of the instance data and type data of the object. The biggest benefit of handle access is that Reference stores a stable handle address, which only changes the instance data pointer in the handle when the object is moved (a very common behavior in garbage collection). Reference itself does not need to be modified.

2.3.2 Direct pointer access

With direct pointer access, the layout of the Java heap object must consider how to place information about the access type data, and the direct stored in Reference is the object address. The biggest benefit of direct pointer access is that it is faster. It saves time for a pointer location, and since objects are accessed frequently in Java, this overhead can add up to a significant execution cost.

Hotpost VMS use direct pointer access.

3 Memory Overflow

Out of memory refers to the fact that the program does not have enough memory space to use when applying for memory. For example, if you request an integer but store it for a long, you are out of memory.

3.1 Java heap Overflow

The Java heap is used to store object instances, and as long as objects are constantly created and there is a reachable path between the GC Roots and the objects to avoid garbage collection, overflow exceptions can occur after the maximum heap capacity is reached. The JVM has to extend the parameters in comments.

Public class HeapOOM {/ Java heap overflow * * * * * - verbose: gc - Xms20M - Xmx20M - XX: + HeapDumpOnOutOfMemoryError * / public static void main(String[] args) throws InterruptedException { ArrayList<OOMObject> oomObjects = new ArrayList<>();while (true){
            oomObjects.add(new OOMObject());
        }
    }

    static class OOMObject{}
}
Copy the code

The following output is displayed:

3.2 VM stack Overflow

The Java Virtual Machine specification describes two types of exceptions: a StackOverflowError is thrown if the stack depth of a thread request is greater than the maximum depth allowed by the virtual machine. An OutOfMemoryError is thrown if the virtual machine cannot allocate enough memory while extending the stack.

public class JavaVmStackSOF {

    private int stackLength = 1;
    public void stackLeak(){ stackLength++; stackLeak(); } /** * virtual stack overflow * -xss128K */ public static void main(String[] args) {JavaVmStackSOF JavaVmStackSOF = new JavaVmStackSOF(); try{ javaVmStackSOF.stackLeak(); }catch (Throwable t){ System.out.println("stack length:"+javaVmStackSOF.stackLength); throw t; }}}Copy the code

Running results:

4 Common JVM command parameters

-Xms20M Indicates that the minimum value of THE JVM startup memory is 20M, and the unit is M. -Xmx20M indicates that the maximum value of the JVM startup memory is 20M, and the unit is M. Setting -xmx and -xms to the same prevents automatic JVM memory expansion. -xmx and -xMS should be set to 10GB, 20GB or even higher for large items. -verbose:gc displays detailed information about the VIRTUAL machine gc. -xss128K indicates that the vm stack can be set to 128K. -xoss128K indicates that the local method stack can be set to 128K. However, HotSpot does not distinguish between virtual machine stacks and local method stacks, so this parameter is not valid for HotSpot. -xx :PermSize=10M indicates the capacity of the permanent generation initially allocated by the JVM, -XX:MaxPermSize=10M Indicates the maximum number of permanent generations that the JVM is allowed to allocate, and must be in M. -xnoclassGC disables garbage collection of classes by the JVM. -xx :+TraceClassLoading Indicates viewing loading information about a class. -xx :+TraceClassLoading indicates viewing unloading information about a class -xx :NewRatio=4 Indicates that young generations are set: the size ratio of old generations is 1:4, which means that young generations account for 1/5 of the heap. -xx :SurvivorRatio=8 Indicates that two Survivor zones are set: The size ratio of 1 Eden area is 2:8, which means that Survivor area accounts for 1/5 of the whole young generation. This parameter is the default Settings for 8 - Xmn20M said the size of the young generation of 20 m - XX: + HeapDumpOnOutOfMemoryError said can make the virtual machine when abnormal memory Dump out the current heap memory Dump snapshot - XX: + UseG1GC Said to let the JVM using G1 garbage collector - XX: + PrintGCDetails said details on the console to print out the GC - XX: + PrintGC said on the console to print out the GC information - XX: PretenureSizeThreshold = 3145728 -XX:MaxTenuringThreshold= Indicates that the age of the object is greater than 1. Automatic old age -xx :CompileThreshold=1000 means a method will be called hot code after 1000 times. -xx :+PrintHeapAtGC to see the heap layout before and after each GC -XX:+PrintTLAB to see the TLAB usage -XX:+UseSpining to turn on the spin -XX:PreBlockSpin To change the number of spins in a spin lock, use this parameter only if the spin lock is enabledCopy the code