A virtual machine is a software implementation physical machine. Java is developed on the basis of WORA (Write Once Run Anywhere), which runs on virtual machines. The compiler converts the Java file into a Java.class file, then the.class file is input to the JVM, which loads and executes the class file. Here is the architecture diagram for the JVM:




First, basic knowledge

(I) JVM instance: JVM instance corresponds to a independently running Java program, which is process level.




(2) JVM execution engine instance: JVM execution engine instance corresponds to the thread belonging to the user running program, it is thread level.




(iii) JVM lifecycle:




(1) Birth of JVM instance

When a Java program is started, a JVM instance is created, and any class that has the public static void main(String[] args) function can be used as the starting point for the JVM instance

(2) Running of JVM instances

Main () is the starting point for the program’s initial thread, which starts any other threads. There are two kinds of threads inside the JVM: daemons and non-daemons. Main () is a non-daemon thread, which is usually used by the JVM itself. Java programs can also identify the threads they create as daemons.

(3) Death of JVM instances

The JVM exits when all non-daemons in the program terminate; The program can also exit using the java.lang.Runtime class or java.lang.system.exit () if the security manager allows it.

Second, the JVM structure




JVMS can be implemented by different vendors. JVM implementations are necessarily different depending on the vendor, but it is possible to implement cross-platform features thanks to the architecture in which the JVM was designed.

The JVM architecture consists of three parts:

Class Loader subsystem

Execution Engine

Runtime Data Area

Java program execution process




Java programs go through two major steps from the creation of the source file to the execution of the program: 1. The source file is compiled into ByteCode by the compiler; 2. The ByteCode is interpreted and executed by the Java virtual machine. Because Java programs are both compiled and interpreted by the JVM, Java is called a “semi-interpreted” language.

Three, run time data area

Program Counter Register, Java Stack, Native Method Stack, Method Area, Heap





(1) Program Counter Register




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. Basic functions such as branching, looping, jumping, exception handling, thread recovery, and so on rely on this counter.

Because multithreading in the Java VIRTUAL machine is implemented by the way threads alternate and allocate processor execution time, at any given moment, one processor (or kernel for multi-core processors) will execute instructions in only one thread. Therefore, 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. We call this kind of memory area “thread private” memory.

According to the JVM specification, if a thread is executing a non-native method, the program counter stores the address of the instruction that is currently being executed. If the thread executes a native method, the value in the program counter is undefined.

Because the amount of space stored in the program counter does not change with the execution of the program, there is no OutOfMemory (OutOfMemory) for program counters.

Java Stack (VM Stack)

The Java Stack, also known as the Java Virtual Machine Stack (Java Vitual Machine Stack), is an in-memory model for the execution of Java methods.

The Java stack holds stack frames, and each stack frame corresponds to a method being called, Stack frames include Local Variables, the Operand Stack, and references to runtime constant pools of the class to which the current method belongs (the concept of runtime constant pools is covered in the methods section) Pool, method Return Address, and some additional information.





When a thread executes a method, it creates a corresponding stack frame and pushes the stack frame. When the method completes execution, the stack frame is pushed off the stack.

There are two types of exceptions StackOverFlowError and OutOfMemoneyError. A StackOverFlowError is raised when the thread request stack is deeper than the virtual machine allows. An OutOfMemoneyError is raised if the vm stack cannot be extended to allocate sufficient memory space. It is thread-private and has the same life cycle as the thread.

The Native Method Stack works in much the same way as the Java Stack. The difference is simply that the Java stack serves the execution of Java methods, while the Native Method stack serves the execution of Native methods.

The specific implementation methods and data structures developed here are not mandated in the JVM specification, and virtual machines are free to implement them. The HotSopt virtual machine directly combines the native method stack with the Java stack.

Like the virtual stack, the local method stack area throws StackOverflowError and OutOfMemoryError exceptions

Method Area

After JDK8 -JVM runtime data area

The Method Area in JDK7 and earlier versions, like the Java heap, is an Area of memory shared by threads that stores information about classes that have been loaded by the virtual machine, constants, static constants, code compiled by the just-in-time compiler, and so on.

A very important part of the method area is the runtime constant pool, which is a runtime representation of the constant pool for each class or interface that is created after the class or interface is loaded into the JVM. Of course, only the contents of the Class file constant pool can be entered into the runtime constant pool. New constants can also be added to the runtime constant pool at run time, such as the String intern method.





In fact, the above code will run differently in JDK6, JDK7, and JDK8. The reason is that the string constant pool was still stored in the method area in JDK6, so it was thrown

OutOfMemoryError: Permanent Space; If the heap is changed to 20M, OutOfMemoryError:Java Heap space; if the heap is changed to 20M, OutOfMemoryError:Java heap space; In JDK8, the method area is completely removed and replaced with Metaspace, so the virtual machine parameter “-xx :MaxPermSize” has no meaning. In its place are “-xx :MetaspaceSize” and “-xx :MaxMetaspaceSize” etc.

In the JVM specification, method areas are not mandated to implement garbage collection. Many people tend to refer to the method area as a “permanent generation” because the HotSpot VIRTUAL machine implements the method area in a permanent generation so that the JVM’s garbage collector can manage this area in the same way as the heap area without having to design a garbage collection mechanism for it. However, since JDK7, the Hotspot VIRTUAL machine has removed the runtime constant pool from the persistent generation.

Heap (Heap)




The largest chunk of managed memory in the JVM. Created when the VM starts.

The only purpose is to hold object instances, and almost all object instances and arrays are allocated here. (The JVM specification says all, but as JIT compilers evolve and escape analysis matures, some instances may not allocate memory in this area.)

The programmer doesn’t have to worry about space release. Java’s garbage collection mechanism takes care of it automatically, so the heap is the main area of garbage collection management and is also known as the “GC heap”.

The heap is shared by all threads, and there is only one heap in the JVM.

Shallow and deep




Shallow Heap and deep Heap are two important concepts. They describe the amount of memory used by an object structure and the amount of memory that can be freed after an object is recycled by GC.

The Shallow Heap is the amount of memory consumed by an object. In a 32-bit system, an object reference would take up 4 bytes, an int would take up 4 bytes, a long would take up 8 bytes, and each object would take up 8 bytes.

Retained Heap is a slightly more complex concept. To understand deep heap, you first need to understand Retained sets. The reserved set of object A refers to the collection of all objects (including object A itself) that can be released after object A is garbage collected. That is, the reserved set of object A can be regarded as the collection of all objects that can only be accessed directly or indirectly through object A. In layman’s terms, it refers to the collection of objects held only by object A. The deep heap is the sum of the shallow heap sizes of all objects in the reserved set of objects.