Runtime data area (program counter + local method stack)

This article introduces two parts of the runtime data area: the program counter and the local method stack, which are both thread private.

Program counter

What is a program counter

The JVM’s Program Counter Register, also known as a Program Counter (PC Register), takes its name from the REGISTERS in the CPU that store the field information related to instructions. The CPU can only run if it loads data into registers.

Instead of a physical register in the broad sense, it would be more appropriate (also known as program hooks) to translate it as a PC counter (or instruction counter), and less likely to cause unnecessary confusion. The PC register in the JVM is an abstract simulation of the physical PC register.

Why do you need a program counter

  • Because the CPU is constantly switching between threads, when it switches back, it needs to know where to start next.

  • The JVM’s bytecode interpreter needs to change the value of the PC register to determine what byte the next bar should execute

Differences between concurrency and parallelism

  • Concurrency: Two or more events inSame time periodhappen
  • Parallelism: Two or more events inAt the same timehappen

role

The PC register is used to store the address to the next instruction and the code of the instruction to be executed. The execution engine reads the next instruction.

The characteristics of

  • It is a small memory space, almost negligible. It’s also the fastest storage area
  • In the JVM specification, each thread has its own program counter, which is thread private and whose life cycle is consistent with that of the thread
  • There is only one method executing on a thread at any time, which is called the current method. The program counter stores the JVM instruction addresses of the Java methods being executed by the current thread; Or, if the native method is actually executed, undefined.
  • It is an indicator of the flow of program control, and basic functions such as branching, looping, jumping, exception handling, and thread recovery depend on this counter
  • The bytecode interpreter works by changing the value of this counter to select the byte code instructions to execute
  • It is the only area where the Java Virtual Machine specification does not specify any OOM conditions

Why is it designed for thread private

We all know that the so-called multi-threaded in a specific period of time will only execute one of the methods, the CPU will constantly do task switching, which will 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 instruction being executed by each thread, it is naturally best to assign a PC register to each thread so that the individual threads can perform independent calculations without interfering with each other.

  • Due to the CPU time slice wheel limit, when many threads are executing concurrently, a processor or a core of a multi-core processor will only execute one instruction from a thread at any given moment.

  • This will inevitably lead to frequent interruptions or recoveries, how to ensure that there is no difference? After each thread is created, it generates its own program counter and stack frame, and the program counter does not affect each thread.

The program counter runs the process

The program counter is used to store the address to the next instruction, which is also the instruction code to be executed. The execution engine reads the next instruction to operate. With the stack frame pushed, the program counter saves a copy of the address to the next stack frame’s method to return the address out of the library. When the stack frame is out of the stack, the program runs correctly to the specified exit according to the return address of the method in the stack frame.

Local method stack

What is a local method stack

Simply put, a Native Method is an interface for Java to call non-Java code. A Native Method is a Java Method whose implementation is implemented in a non-Java language, such as C. When defining a Native method, the implementation is not provided (somewhat like defining a Java Interface) because the implementation is implemented outside of the Java language.

The purpose of the native interface is to fuse different programming languages for Java. It was originally intended to fuse C/C++ programs.

Why use local methods

  • Java is very convenient to use, but there are some level tasks that are not easy to implement in Java, or if we are concerned about the efficiency of the program, we need a lower level language and faster performance.

  • Sometimes Java applications need to interact with environments outside of Java, which is the main reason native methods exist. Native methods are just such a communication mechanism: they give us a very clean interface, and we don’t need to know the details outside of Java applications.

  • Virtual machines are written in C++, and some operating system features are not encapsulated in the Java language, so it is difficult for us to implement them by ourselves.

  • For my use, the most faster and more convenient operation efficiency

The characteristics of

  • The Java virtual machine stack is used to manage calls to Java methods, and the local method stack is used to manage calls to local methods.

  • The local method stack is also thread private. Allows memory sizes to be implemented as fixed or dynamically expandable. (Same in terms of memory overflow)

    • The Java VIRTUAL Machine will throw a StackOverflowError exception if a thread requests a stack allocation that exceeds the maximum allowed by the local method stack.
    • The Java VIRTUAL Machine will throw an OutOfMemoryError if the local method stack can be dynamically extended, and there is not enough memory to apply for when trying to extend it, or if there is not enough memory to create the corresponding local method stack when creating a new thread.
  • The native methods are implemented using the C language.

  • The specific approach is to register Native methods in the Native Method Stack and load the local Method library when the Execution Engine executes.

  • When a thread calls a local method, it enters a whole new world that is no longer constrained by the virtual machine. It has the same permissions as the virtual machine.

    • Local methods can access the runtime data area inside the VIRTUAL machine through the local method interface.
    • It can even use registers directly from the local processor
    • Allocate any amount of memory directly from the heap of local memory.
  • Not all JVMS support native methods. This is because the Java Virtual Machine specification does not explicitly require the language, implementation, data structure, and so on of the native method stack. If the JVM product is not intended to support native methods, you may not need to implement a native method stack.

Native methods in hotSpot

Virtual machine stack and local method stack running process

Any local method interface uses some kind of local method stack. When a thread calls a Java method, the virtual machine creates a new stack frame and pushes it into the Java stack (virtual machine stack). However, when it calls a local method, the virtual machine keeps the Java stack unchanged and instead of pushing new frames into the thread’s Java stack, the virtual machine simply dynamically connects and calls the specified local method directly.

If a virtual machine implements a native method interface that uses the C connectivity model, then its native method stack is the C stack. When a C program calls a C function, its stack operations are determined. The arguments passed to the function are pushed on the stack in a certain order, and its return value is passed back to the caller in a certain way. This is the behavior of a virtual machine implementing a local method stack.

When the local method interface needs to call back Java methods in the Java virtual Machine, in this case, the thread saves the state of the local method stack and goes to another Java stack.

When a thread calls a local method, the local method calls back another Java method in the virtual machine. This figure shows the full picture of threads running inside the JAVA virtual Machine. A thread may execute Java methods throughout its lifetime, manipulating its Java stack; Or it might jump between the Java stack and the native method stack without any difficulty.

The thread first calls two Java methods, and the second Java method calls a local method, causing the virtual machine to use a local method stack.

Suppose you have a C stack with two C functions in between. The first C function is called as a native method by a second Java method, which in turn calls a second C function.

The second C function then calls back a Java method (a third Java method) through the native method interface, which eventually calls a Java method (which becomes the current method in the diagram).

The status quo

This approach is now used less and less, except for hardware-related applications, such as driving a printer with a Java program or managing a production device with a Java system, and is rarely seen in enterprise applications. Because the current heterogeneous domain communication is very developed, such as the use of Socket communication, can also use Web Service and so on, here is not much to introduce.