Java - runtime stack frame structure

Overview

A stack frame is a data structure used to support the virtual machine for method invocation and method execution. It is the stack element of the virtual machine stack in the virtual machine runtime data area.

The stack frame stores the method's local variable table, operand stack, dynamic connection and method return address and other information.

The process from the start of the call to the completion of the execution of each method corresponds to the process of a stack frame from being pushed to the stack in the virtual machine.

When compiling the program code, the size of the local variable table and the depth of the operand stack in the stack frame are completely determined.

Therefore, how much memory a stack frame needs to allocate will not be affected by the variable data at the runtime of the program, but only depends on the specific virtual machine implementation.

write picture description here

In an active thread, only the stack frame at the top of the stack is valid, which is called the current stack frame, and the method associated with this stack frame is called the current method.



local variable table

We mentioned in the virtual machine stack in the Java memory area : For us, the main focus of the stack stack memory is the local variable table part of the virtual machine stack.

That is to say, the local variable table plays a pivotal role in the stack.

The Local Variable Table is a set of variable value storage spaces used to store method parameters and local variables defined inside the method. And when Java is compiled into a Class file, the maximum capacity of the local variable table that needs to be allocated by the method has been determined .


Variable Slot

The capacity of the local variable table takes the variable slot as the smallest unit, and each variable slot can store 32-bit memory space, such as boolean, byte, char, short, int, float, reference.

For 64-bit data types (long, double), the virtual machine allocates two consecutive Slot spaces in high-order alignment, which is equivalent to dividing one read and write of long and double data types into two 32-bit reads and writes .

  • reference (object instance reference) Generally speaking, the virtual machine can directly or indirectly find the following two points of the object from the reference  : 
    ① The starting address index of the data stored in the Java heap  .
    ②The type data of the data type stored in the method area .
plastic byte(b) bit
byte 1 1*8
short 2 2*8
int 4 4*8
long 8 8*8


floating point byte(b) bit
folate 4 4*8
double 8 8*8


Char type byte(b) bit
char 2 2*8


boolean type byte(b) bit
boolean 1 1*8

PS : 8bit=1b,1024b=1kb


When the method is executed, the virtual machine uses the local variable table to complete the transfer process of parameter values ​​to the parameter variable list. If an instance method is executed, the slot at the 0th index in the local variable table is used to transfer the object instance to which the method belongs by default. citations. this( This implicit parameter can be accessed by keyword in the method ).

The remaining parameters are arranged in the order of the parameter table, occupying the local variable Slot starting from 1.


  • Slot reuse 
    In order to save the stack frame space as much as possible, the Slot in the local variable table can be reused, that is to say, when the instruction of the PC counter has exceeded the scope of a variable (execution is completed), then the variable corresponding to Slot can be handed over to other variables for use. 
    Advantage:  save stack frame space.  
    Disadvantage:  affects the garbage collection behavior of the system. (For example, if a large method occupies more Slots, and the Slot is not assigned or emptied after the scope of the method is executed, the garbage collector will not be able to reclaim the memory in time.)



dynamic link

Each stack frame contains a reference to the method in the runtime constant pool to which the stack frame belongs. This reference is held to pay for dynamic linking during method invocation.

在类加载阶段中的解析阶段会将符号引用转为直接引用,这种转化也称为静态解析。另外的一部分将在每一次运行时期转化为直接引用。这部分称为动态连接。(关于这部分,后面会再继续分析)



方法返回地址

当一个方法开始执行后,只有2种方式可以退出这个方法 :

  • 方法返回指令 : 执行引擎遇到一个方法返回的字节码指令,这时候有可能会有返回值传递给上层的方法调用者,这种退出方式称为正常完成出口。

  • 异常退出 : 在方法执行过程中遇到了异常,并且没有处理这个异常,就会导致方法退出。

无论采用任何退出方式,在方法退出之后,都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在栈帧中保存一些信息。

一般来说,方法正常退出时,调用者的PC计数器的值可以作为返回地址,栈帧中会保存这个计数器值。

而方法异常退出时,返回地址是要通过异常处理器表来确定的,栈帧中一般不会保存这部分信息。



操作数栈

操作数栈和局部变量表一样,在编译时期就已经确定了该方法所需要分配的局部变量表的最大容量。

操作数栈的每一个元素可用是任意的Java数据类型,包括long和double。32位数据类型所占的栈容量为1,64位数据类型占用的栈容量为2。

当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的,在方法执行的过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈 / 入栈操作

例如,在做算术运算的时候是通过操作数栈来进行的,又或者在调用其它方法的时候是通过操作数栈来进行参数传递的。


参数传递

write picture description here

索然两个栈帧作为虚拟机栈的元素是完全独立的,但是虚拟机会做出相应的优化,令两个栈帧出现一部分重叠。

As shown in the figure above, part of the operand stack of the stack frame overlaps with the local variable table of the previous stack frame, so that part of the data can be shared when the method is called, and there is no need to copy and transfer additional parameters.


arithmetic operations

The instruction stream output during Java compilation is a stack-based instruction set architecture.

For example, let's look at a simple arithmetic code:

write picture description here

View bytecode instructions through javap:

write picture description here

First, this code requires an operand stack with a depth of 2 and a local variable space of 4 slots. The following pictures are quoted from "Understanding Java Virtual Machine II" to describe the results of code execution, the changes in the operand stack and the local variable table.


write picture description here

First of all, the Slot at the 0th index in the local variable table is used to pass the reference of the object instance to which the method belongs by default.

And push 100 onto the operand stack.



write picture description here

The value of the operand stack is then popped off the stack and stored in the local variable table.



write picture description here
write picture description here

Copy (push) the value to be operated on into the operand stack.



write picture description here
write picture description here

The operand stack operation (100+200) is popped from the stack, and the result (300) is pushed onto the stack. (because the operation has to continue).

Finally, a multiplication operation is required, and the value 300 is pushed onto the stack.



write picture description here

Reprinted from: https://blog.csdn.net/qian520ao/article/details/79118474

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326151786&siteId=291194637