My JVM study notes: Chapter 3-Runtime Data Area (1)

My JVM study notes: Chapter 3-Runtime Data Area (1)

Thanks to Mr. Song Hongkang from Shang Sigu for the JVM entry to the proficient course, and salute every teacher who teaches free courses attentively!
This set of tutorials are all my study notes after the course, to prevent forgetting, and send to everyone to share, thank you for viewing~

This chapter contains knowledge points: overview of running data area, detailed explanation of program counter, overview of virtual machine stack, execution process of virtual machine stack, StackOverFlowError and OutOfMemoryError in virtual machine stack, and how to set the size of virtual machine stack!

1. Runtime data area structure

Note: Different JVMs have different mechanisms for memory management. This note only discusses the memory structure of the Hotspot virtual machine!
Let’s take a look at the official runtime data area structure: The
Runtime data area structure
runtime data area is mainly composed of the following parts:

  • Method area: the information after the class is loaded will be stored in the method area
  • Heap: responsible for storing object data
  • Program counter: used to record where the code runs
  • Local method stack: similar to the virtual machine stack, responsible for executing methods written in other languages ​​(such as calling C language methods)
  • Virtual machine stack: A stack frame corresponds to a method, and the virtual machine stack describes the memory model of the corresponding JVM when the method is executed (the method is executed by the execution engine in the virtual machine stack).

Detailed legend:
JVM runtime data area
Note: After JDK8, the HotSpot virtual machine uses meta space instead of the method area. The function and structure of the two are basically the same!

Multi-threaded processing mechanism in JVM: A
thread is a running unit in a program. JVM allows an application to be executed in parallel by multiple threads.
The relationship between Java threads and native threads:
In HotspotJVM, each thread is directly mapped to the native thread of the operating system. When a Java thread is ready for execution, a native thread of the operating system is also created at the same time. After the Java thread execution terminates, the local thread will also be recycled. The operating system is responsible for the scheduling of all threads to any available CPU. Once the local thread is initialized successfully, it will call the run () method in the Java thread. When the last non-daemon thread ends, the JVM will also end.
The structure of the runtime data area and the existing relationship
as shown in the first picture: the
red area (heap area, method area): shared between threads, only one copy exists in a JVM process!
Gray area (program counter, local method stack, virtual machine stack): it is thread independent, that is, if there are 5 threads in a process, there are 5 points of program counter, local method stack, and virtual machine stack. And it is created as the thread is created, and destroyed as the thread is destroyed!

In conclusion:
The runtime data area of ​​JVM consists of 5 parts, namely: heap area, method area, program counter, local method stack, and virtual machine stack!
Among them: the heap area and the method area are shared among threads, while the program counter, local method stack, and virtual machine stack are exclusively shared by threads!

2. Program counter

Program Counter Register (Program Counter Register) is abbreviated as program counter, PC register.The program count register is not a register in the hardware sense, but an abstraction of the physical register(It can be understood as a program hook/line number indicator), it is the fastest memory area in the entire program,Used to record the address of the next instruction of the Java program running in the current thread(The line number of the code to be executed in the next line), the execution engine can read the next instruction and execute it.

In summary:
it is an indicator of program control flow. Basic functions such as branches, loops, jumps, exception handling, and thread recovery all need to rely on this counter to complete.

note:

  • Each thread has an independent program counterParallel thread private, The life cycle is consistent with the thread!
  • If the Native method is currently being executed, the program register has no effect and the value is always undefined!
  • When the bytecode interpreter works, it selects the next bytecode instruction to be executed by changing the value of this counter.
  • It is the only area that does not specify any OutOtMemoryError conditions in the Java Virtual Machine Specification.

Question: Why use the program counter to record the line number?
Because the CPU needsConstantly switch between threads, After switching back at this time, you have to know the nextWhere to continue execution. JVM wordSection code interpreterIt is necessary to change the value of the PC register to determine what bytecode instruction should be executed next.

Question 2: Why should the program counter be set as thread private?
we all knowThe so-called multi-threaded method will only execute one of the threads in a specific time period, The CPU will keep doingTask switching, This will inevitably lead to frequent interruption or recovery, how to ensure that there is no difference in points? In order to accurately record the current bytecode instruction address being executed by each thread, the best way is naturallyEach thread allocates a PC register, So that each thread can beIndependent calculation, So that there will be no mutual interference.

Example: View the program line number in bytecode

public class TestPCRegister {
    
    
    public static void main(String[] args) {
    
    
        int a = 10;
        int b = 20;
        int c = a + b;
        System.out.println(c);
    }
}

Decompilation command:

javap –v 文件名

At this time, we can find that there is a corresponding position before each line of code in the bytecode fileLine number, These line numbers are the contents stored in the program counter. When a line is executed, the execution engine willNext line of code line numberWrite the program counter so that even if the CPU time slice is robbed, it can be determined when the execution continuesCode location to be executed, To ensure that the program will not go wrong!
Decompilation result

3. Overview of the virtual machine stack

What is the
Java virtual machine stack: Java Virtual Machine Stack (Java Virtual Machine Stack), also called Java stack in the early days. Each thread creates a virtual machine stack when it is created, and its internalSave one stack frame(Stack Frame) ,Corresponds to the Java method calls again and again. The virtual machine stack isThread privateYes, the life cycle is the same as the thread.
Supervisor of Virtual Machine StackJava program operation, It saves the local variables and partial results of the method, and participates in the call and return of the method.

Features of heap and stack:
The stack is the unit of runtime, and the heap is the unit of storage.
That is: the stack solves the running problem of the program, that is, how the program is executed, or how to process the data. The heap solves the problem of data storage, that is, how and where to put the data.

The advantages and disadvantages of the virtual machine stack: the
advantage is that it is cross-platform, the instruction set is small, and the compiler is easy to implement, the disadvantage is that the performance is reduced, and the same function requires more instructions.

Introduction to stack frame: The stack frame
is the basic unit in the virtual machine stack.Each method corresponds to a stack frame, And the JVM execution method is to carry out a stack framePush operation, And then executed by the execution engine, after the execution is complete, this stack frame will executePop operation

That is: each method corresponds to a stack frame, the execution of the method will push the stack frame, and the end of the execution will pop the stack frame!

The execution process of the virtual machine stack:
JVM has only two direct operations on the Java stack, namely the stack framePush and pop,follow"First in last out"/"last in first out"Principle.
That is: when the JVM executes a method,The stack frame corresponding to this method will be pushed into the virtual machine stack first, Execute the code in the period in turn, when other methods are called in the method ==, the stack frame corresponding to the called method will be pushed into the virtual machine stack ==, and thenTake the lead in executing the method that finally pushes into the virtual machine stack, When the top-level method is executed, it will pop the stack, and then continue to execute his next-level method!
The top-level method is called "Current stack frame", the corresponding method is "Current method", the class that defines the method is called "Current class"!
Practical demonstration:

public class TestStack {
    
    

    public static void main(String[] args) {
    
    
        System.out.println("main方法开始执行");
        method1();
        System.out.println("main方法执行结束");
    }

    public static void method1()
    {
    
    
        System.out.println("method1方法开始执行");
        method2();
        System.out.println("method1方法执行结束");
    }

    public static void method2()
    {
    
    
        System.out.println("method2方法开始执行");
        method3();
        System.out.println("method2方法执行结束");
    }

    public static void method3()
    {
    
    
        System.out.println("method3方法开始执行");
        System.out.println("method3方法执行结束");
    }
}

Results of the:

Results of the

At this
Debug result
time, we debug the program: At this time, we define four methods, each method corresponds to a stack frame, when the main method starts to execute, the stack frame corresponding to the main method will be pushed onto the stack, and then method1 is called Method, the virtual machine will push the method2 method onto the stack, and the main method is not executed at this time, so the main method will not be popped out of the stack, but will be sorted after the method1 method. At this time, method1 is the current stack frame , The program will continue to execute the code of method1, and method1 calls method2... and so on. When method3 is executed, the virtual machine pushes method3 onto the stack, and method1, method2, and main methods are not executed, so this There are four stack frames in the virtual machine stack. When method3 is executed, method3 will pop out. At this time, there are only 3 stack frames left in the virtual machine stack, and method2 is the current stack frame... By analogy, when the method1 method is executed, only the stack frame of the main method remains in the virtual machine stack, and the execution engine will execute the remaining code of the main method in turn!
A detailed description
note:

  • The stack frames contained in different threads are not allowed to reference each other, that is, it is impossible to reference the stack frame of
    another thread in one stack frame.
  • If the current method calls other methods, when the method returns, the current stack frame will return the execution result of this method
    to the previous stack frame. Then, the virtual machine discards the current stack frame so that the previous stack frame becomes the current stack frame again.
    Java methods have two ways to return functions, one is normal function return, using the return instruction; the other
    is throwing an exception. No matter which method is used, the stack frame will be popped.

Set the stack size and exception handling: The
Java Virtual Machine specification allows the size of the Java stack to be dynamic or fixed. If a fixed-size Java virtual machine stack is used, the Java virtual machine stack capacity of each thread can be independently selected when the thread is created. If the stack capacity allocated by the thread request exceeds the maximum capacity allowed by the Java virtual machine stack, the Java virtual machine will throw a StackOverFlowError exception.
If the Java virtual machine stack can be dynamically expanded, and cannot apply for enough memory when trying to expand, or there is not enough memory to create the corresponding virtual machine stack when creating a new thread, the Java virtual machine will throw a OutOfMemoryError is abnormal.

In other words:
because every stack frame has a size, the size of the stack frame is related to the method code!
If the stack size does not change, then if too many methods are executed at the same time, the virtual machine stack space will be filled with stack frames. At this time, if you continue to call methods and stack frames are added, the stack will overflow and cause StackOverFlowError.
If the size of the stack changes dynamically, at this time, if the stack is filled, the JVM will automatically expand the space of the stack, but if the memory is insufficient at this time, it will cause a memory overflow, and an OutOfMemoryError will be reported!

For example:
if the stack size is fixed, then the easiest way to cause StackOverFlowError is to call the method recursively. Each call will push a new stack frame onto the stack! When there are too many recursions and the stack frame is full of the virtual machine stack, an exception will be thrown!

	public class TestStack {
    
    
    public static int i=0;
    public static void main(String[] args) {
    
    
        System.out.println(i++);
       main(args);
    }
}

Output result:
Output result
At this time, we see that we have caused the program to recurse due to the wrong logic, the stack frame is full of the virtual machine stack, and finally the virtual machine stack can no longer accommodate a new stack frame when the 9773th stack frame is pushed into the stack. Throw an exception!

Set the size of the virtual machine stack: we
can see that an exception occurred due to logic errors in front of us. If many methods must be executed at the same time when the program is running, then we must set the size of the virtual machine stack to avoid exceptions!

Set the virtual machine stack size instruction:

-Xss *k

Example: Set the above program to different virtual machine stacks
Set the size of the stack
result
At this time: We set the virtual machine stack to 108k (minimum requirement), and found that only 978 methods can be executed at the same time!

Set the size of the virtual machine stack
result

And set the virtual machine stack size to 4096k, you can perform more methods!

Guess you like

Origin blog.csdn.net/qq_42628989/article/details/104360779