Java-JVM stack frame (Stack Frame)

I. Overview

Stack frame location

When the need to load various kinds of data performed by the JVM Java program into memory, different data stored in different memory area (logically), the data memory area called a runtime data area (the Run-Time the Data Areas) .

Which JVM Stack (Stack stack or virtual machine, thread stack, stack) is stored in Stack Frame (Frame or stack frame, stack method).

Correspondence between

A thread corresponds to a JVM Stack. JVM Stack contains a set of Stack Frame. Each thread calls a method on the corresponding JVM Stack of Stack Frame of the stack, the method completes or terminates abnormally corresponds to a stack (destroyed).

When calling a Java JVM method, the type of information it gets from the corresponding class of this method the local variables and operand stack size, and accordingly allocate memory stack frame, the stack is then pressed into the JVM.

In active threads, only the top of the stack is located in the stack frame is valid, it called the current stack frame, and this method is called a stack frame associated with the current method.

Stack frame structure

How much memory a stack frame needs to be allocated, the program will not be affected runtime variable data, but only depending on the particular virtual machine implementation.

Local variables table (Local Variable Table)

  • The stack frame can be determined how much of the local variable table, a specific size can be seen in the Class file when compiling the compiled program code.
  • Capacity in the local variable table Variable Slot (variable slot) as a minimum unit, each variable slot lengths may store 32-bit memory space.
  • When performing the method, the virtual machine uses the local variable table to complete the transfer process parameter value of the parameter variables list, if the example method is performed, then the local variable table index of Slot 0 is the default delivery method for the object instance belongs references (in the method may be accessed through the implicit parameter keyword this).
  • Other parameters according to the parameter table is arranged in order, from a local variable occupancy starting Slot.
  • And basic types of data and references to returnAddress (return address) occupies a variable slot, long and double take two.

操作数栈(Operand Stack)

  • 同样也可以在编译期确定大小。
  • Frame 被创建时,操作栈是空的。操作栈的每个项可以存放 JVM 的各种类型数据,其中 long 和 double 类型(64位数据)占用两个栈深。
  • 方法执行的过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈和入栈操作(与 Java 栈中栈帧操作类似)。
  • 操作栈调用其它有返回结果的方法时,会把结果 push 到栈上(通过操作数栈来进行参数传递)。

动态链接(Dynamic Linking)

  • 每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态链接。
  • 类加载阶段中的解析阶段会将符号引用转为直接引用,这种转化也称为静态解析。另外的一部分将在运行时转化为直接引用,这部分称为动态链接。

返回地址(Return Address)

  • 方法开始执行后,只有 2 种方式可以退出 :方法返回指令,异常退出。

帧数据区(Stack Data)

  • 帧数据区的大小依赖于 JVM 的具体实现。

 

二、反编译代码

源代码

package com.jvm;

/**
 * 编译:javac com\jvm\StackFrame.java
 * 反编译:javap -p -v com\jvm\StackFrame.class
 */
public class StackFrame {
    public static void main(String[] args) {
        add(1, 2);
    }

    private static int add(int a, int b) {
        int c = 0;
        c = a + b;
        return c;
    }
}
View Code

反编译后的字节码(去除了不相关字节码)

{
  public com.jvm.StackFrame();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 7: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: iconst_1
         1: iconst_2
         2: invokestatic  #2                  // Method add:(II)I
         5: pop
         6: return
      LineNumberTable:
        line 9: 0
        line 10: 6

  private static int add(int, int);
    descriptor: (II)I
    flags: ACC_PRIVATE, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=2
         0: iconst_0
         1: istore_2
         2: iload_0
         3: iload_1
         4: iadd
         5: istore_2
         6: iload_2
         7: ireturn
      LineNumberTable:
        line 13: 0
        line 14: 2
        line 15: 6
}

 

三、字节码解释

主要看 add 方法

# 方法描述
# 括号内为入数类型,这里为两个 int 型入参
# 括号外为返回类型,这里为返回 int 型
descriptor: (II)I

# 方法类型,这里为私有的静态方法
flags: ACC_PRIVATE, ACC_STATIC


# 操作数栈为 2
# 本地变量容量为 3
# 入参个数为 2
stack=2, locals=3, args_size=2

执行 add(1,2) 的过程,最后 ireturn 会将操作数栈栈顶的值返回给调用者

LineNumberTable 为代码行号与字节码行号的对应关系


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

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5

https://www.cnblogs.com/caca/p/jvm_stack_frame.html

https://www.artima.com/insidejvm/ed2/jvm8.html

Guess you like

Origin www.cnblogs.com/jhxxb/p/11001238.html