栈与栈帧
Java Virtual Machine Stacks (Java 虚拟机栈)
- JVM 中由堆、栈、方法区所组成,其中栈内存是给线程使用,
- 每个线程启动后,虚拟机就会为其分配一块栈内存。
- 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存
- 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
具体示例如下 :
package cn.knightzz.example.e2.source;
public class TestFrame {
public static void method1(int n) {
Object m = method2(n + 1);
System.out.println("m = " + m);
}
public static Object method2(Object n) {
return n;
}
public static void main(String[] args) {
method1(10);
}
}
当我们运行到主线程method1(10)
时, 可以看到只有主线程在活动
而当我运行到method2(n+1)
位置时 当前的活动栈帧对应着 method1
继续运行直到运行到 method2
时可以看到此时有三个栈帧, 活动栈帧是 method2
, 所以
- 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存
- 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
栈帧图解
代码示例
package cn.knightzz.example.e2.source;
/**
* @author 王天赐
* @title: TestFrame
* @projectName hm-juc-codes
* @description: 线程的栈帧
* @website <a href="http://knightzz.cn/">http://knightzz.cn/</a>
* @github <a href="https://github.com/knightzz1998">https://github.com/knightzz1998</a>
* @create: 2022-06-15 22:18
*/
public class TestFrame {
public static void method1(int n) {
Object m = method2(n + 1);
System.out.println("m = " + m);
}
public static Object method2(Object n) {
return n;
}
public static void main(String[] args) {
method1(10);
}
}
初始状态如下 :
- 所有的代码加载进方法区, JVM虚拟机为主程序分配栈内存
执行主方法, 创建 main
栈帧
局部变量表 :
- 存储局部变量以及方法参数, 对于main函数来说, 局部变量表存储的就是
args
args
存储的是执行程序的命令信息 :java -jar -Xmx2G
后面的参数信息
继续向下执行, 执行到 method1
方法内是 , 此时注意 :
- 程序计数器里记录了此时程序的位置 :
method1(10)
, 随着继续向下执行, 程序计数器会记录执行的每一行代码 - 返回地址指向方法区里
main
函数位置的method1(10)
位置 - 局部变量存储了
n
和m
两个变量, 一个是方法输入参数, 一个是对象 - 注意 : 对象是存储在堆中的
当我们继续向下执行时, 执行到 method2
:
- 返回地址指向
method1
中调用method2
的位置
当最后一个方法 method2 执行结束后, 会根据返回地址逐步返回, 直到结束