JVM系列(2):Java虚拟机栈
栈的介绍
栈也叫栈内存,主管 Java 程序的运行,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束该栈就 Over,生命周期和线程一致,是线程私有的。8 种基本类型的变量+对象的引用变量+实例方法都是在函数的栈内存中分配。
栈的存储
栈帧中主要保存 3 类数据:
1.本地变量(Local Variables):输入参数和输出参数以及方法内的变量;
2.栈操作(Operand Stack):记录出栈、入栈的操作;
3.栈帧数据(Frame Data):包括类文件、方法等等
运行原理
栈中的数据都是以栈帧(Stack Frame)的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集,在java层面,方法如果没有进入JVM叫方法,进了JVM 的栈则叫栈帧
如图
当一个方法 A被调用时就产生了一个栈帧 F1,并被压入到栈中,
A 方法又调用了 B 方法,于是产生栈帧 F2 也被压入栈,
B 方法又调用了 C 方法,于是产生栈帧 F3 也被压入栈,
......
执行完毕后,先弹出 F3 栈帧,再弹出 F2 栈帧,再弹出 F1 栈帧......
遵循“先进后出”原则。
如图所示
每执行一个方法都会产生一个栈帧,保存到栈(后进先出)的顶部,顶部栈就是当前的方法,该方法执行完毕 后会自动将此栈帧出栈。
栈内存溢出
如 果 一 个 线 程 在 计 算 时 所 需 要 用 到 栈 大 小 大于 配 置 允 许 最 大 的 栈 大 小 , 那 么 Java 虚 拟 机 将 抛 出StackOverflowError。
栈内存溢出错误:Exception in thread "main" java.lang.StackOverflowError,StackOverflowError不是异常,是错误
编写一个栈堆溢出程序:递归调用方法,当Java栈里面的内存不够用了,就出现错误
栈、堆、方法区的交互关系
我们知道,HotSpot 是使用指针的方式来访问对象:Java 堆中会存放访问类元数据的地址,reference 存储的就直接是对象的地址
比如我创建一个实例 Person person = new Person();
person是一个引用:存放在Java栈里
new Person()是一个实例:存放在堆里
如下代码:
package classloader; public class Test { public void changeRef(Person person2) { person.setName("steak"); }public static void main(String[] args) { Test test = new Test(); Person person1 = new Person("刘牌"); test.changeRef(person1); System.out.println(person1); } } class Person { String name; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } }
基本类型(八大数据类型)传值,引用类型传内存地址
刚开始person1指向值为刘牌的这个地址,然后main方法调用changeRef(Person person),于是person2又指向同一个地址,但是它的值为steak,所以值就变成steak,虽然是同一个地址,但是值已经不在是以前的那个值
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端