Note source: Silicon Valley JVM complete tutorial, millions of playback, the peak of the entire network (Song Hongkang details Java virtual machine)
Update: gitee.com/vectorx/NOT…
Codechina.csdn.net/qq_35925558…
Github.com/uxiahnan/NO…
[TOC]
3. Runtime data area and program counter
3.1. Run time data area
Summary of 3.1.1.
This section focuses on the runtime data area, which is shown in the following figure, after the class has been loaded
Once we have passed the previous stages of loading the class -> verifying -> preparing -> parsing -> initialization, we will use the execution engine to use our class, and the execution engine will use our runtime data area
Memory is a very important system resource. It is the intermediate warehouse and bridge between hard disk and CPU. It carries the real-time running of operating system and application program. There are some differences in how memory is divided and managed by different JVMS. Take a look at the classical JVM memory layout in conjunction with the JVM virtual machine specification.
We think of what’s behind the chef (chopped dishes, knives, spices) as the run-time data area. A chef can be likened to an executive engine, making beautiful dishes out of what is prepared
The data we get from disk or network IO needs to be loaded into memory, and then the CPU retrieves data from memory for reading. In other words, memory acts as a bridge between the CPU and disk
The Java virtual machine defines several run-time data areas that are used by programs while they are running, some of which are created when the virtual machine is started and destroyed when the virtual machine exits. Others are thread-specific, with thread-specific data areas created and destroyed as threads start and end.
The gray ones are private to a single thread, and the red ones are shared by multiple threads. That is:
- Each thread: independently includes program counter, stack, local stack.
- Inter-thread sharing: heap, off-heap memory (permanent generation or meta-space, code cache)
There is only one Runtime instance per JVM. The runtime environment is the equivalent of that box in the middle of the memory structure: runtime environment.
3.1.2. Thread
A thread is a unit of execution within a program. The JVM allows an application to have multiple threads running in parallel. In Hotspot JVM, each thread maps directly to the operating system’s native thread.
When a Java thread is ready to execute, an operating system native thread is created at the same time. When Java thread execution terminates, the local thread also recycles.
The operating system is responsible for scheduling all threads to any available CPU. Once the local thread initializes successfully, it calls the run() method in the Java thread.
3.1.3. JVM system threads
If you use Console or any debugging tool, you’ll see a lot of threads running in the background. These background threads do not include the main thread that calls public static void main(String[] args) and all threads created by the main thread itself.
The main backend threads in the Hotspot JVM are:
- Virtual machine threads: This thread operation does not occur until the JVM reaches a safe point. The reason these operations must occur in different threads is that they all need the JVM to reach a safe point so that the heap does not change. The types of execution of this thread include “stop-the-world” garbage collection, thread stack collection, thread suspension, and partial lock cancellation.
- Periodic task threadThese threads are representations of periodic events (such as interrupts), and they are typically used for scheduled execution of periodic operations.
- The GC threadThis thread provides support for different kinds of garbage collection behavior within the JVM.
- Compilation thread: this thread compiles bytecode to native code at run time.
- Signal scheduling thread: This thread receives the signal and sends it to the JVM, which processes it internally by calling the appropriate method.
3.2. Program counter (PC register)
The Program Counter Register in the JVM is named after the CPU Register, which stores instruction related field information. The CPU can only run if it loads data into a register. Instead of referring to a physical register in a broad sense, it might be more appropriate to translate it as a PC counter (or instruction counter) (also known as a program hook) and less likely to cause unnecessary misunderstanding. The PC register in the JVM is an abstract simulation of the physical PC register.
role
The PC register is used to store the address pointing to the next instruction and the instruction code to be executed. The execution engine reads the next instruction.
It’s such a small amount of memory that you can barely remember it. It is also the fastest storage area.
In the JVM specification, each thread has its own program counter, which is thread-private and whose lifetime is consistent with that of the thread.
There is only one method executing per thread at any one time, which is called the current method. The program counter stores the JVM instruction address of the Java method being executed by the current thread; Or, if you are executing a native method, undefined.
It is an indicator of program control flow, and basic functions such as branching, looping, jumping, exception handling, thread recovery, and so on rely on this counter.
The bytecode interpreter works by changing the value of this counter to select the next bytecode instruction to execute.
It is the only area where the Java Virtual Machine specification does not specify any OutofMemoryError cases.
For example
public int minus(a){
intc = 3;
intd = 4;
return c - d;
}
Copy the code
Bytecode files:
0: iconst_3
1: istore_1
2: iconst_4
3: istore_2
4: iload_1
5: iload_2
6: isub
7: ireturn
Copy the code
What is the use of using PC registers to store byte code instruction addresses? Why use a PC register to record the execution address of the current thread?
Since the CPU is constantly switching threads, it needs to know where to start after switching back.
The JVM’s bytecode interpreter needs to change the value of the PC register to figure out what bytecode instructions to execute next.
Why are PC registers private?
We all know the so-called multithreading in a specific period of time will only execute one of the methods of a thread, CPU will keep doing task switching, so inevitably lead to frequent interruption or recovery, how to ensure that there is no difference? In order to accurately record the address of the current bytecode instructions being executed by each thread, it is naturally best to assign each thread a PC register so that each thread can compute independently without interfering with each other.
Due to the CPU time wheel limit, a single processor or core of a multi-core processor will execute only one instruction in a particular thread at any given time during the concurrent execution of multiple threads.
This will inevitably lead to frequent interruptions or recovery, how to ensure that there is no difference? After each thread is created, it will generate its own program counter and stack frame. Program counter does not affect each thread.
CPU time slice
The CPU time slice is the time that the CPU allocates to each program. Each thread is allocated a time segment, called its time slice.
On a macro level: You can open multiple applications at the same time, each running in parallel.
But on a micro level: since there is only one CPU and only a portion of the program’s requirements can be processed at a time, one way to deal with fairness is to introduce time slices that each program executes in turn.