0

0

详解JVM中的栈帧结构_局部变量表、操作数栈与动态链接的作用

P粉602998670

P粉602998670

发布时间:2026-02-15 03:11:32

|

979人浏览过

|

来源于php中文网

原创

局部变量表存储编译期分配索引位置的变量值,long和double占两个槽因其8字节且需连续槽位对齐;操作数栈采用出栈入栈模型以匹配表达式求值顺序并优化性能;动态链接通过类加载时解析符号引用或运行时invokedynamic绑定实现方法目标定位。

详解jvm中的栈帧结构_局部变量表、操作数栈与动态链接的作用

局部变量表存的是什么,为什么longdouble占两个槽

局部变量表不是按“变量名”存数据,而是按“编译期分配的索引位置”存值。每个槽(slot)固定 4 字节,intfloatreferencereturnAddress各占 1 槽;longdouble 占 2 槽,因为它们是 8 字节,且 JVM 要求连续槽位对齐。

常见错误现象:VerifyError: Operand stack overflow 或方法调用后读到错误值,往往是因为手动计算 slot 索引时没跳过 long/double 占用的第二个槽,导致后续变量写入错位。

  • 实例方法的局部变量表第 0 号槽固定存 this 引用(静态方法没有)
  • 编译器可能复用槽位:比如 int a = 1; {...} int b = 2;ab 可能共用同一槽
  • Java 8+ 的 -g:vars 编译选项才能在调试信息里看到变量名与槽号的映射,否则仅靠字节码无法反推原始变量名

操作数为什么是“出栈入栈”模型,而不是数组下标访问

操作数栈本质是为字节码指令服务的临时工作区,设计成栈结构是为了匹配绝大多数表达式求值顺序(如 iadd 总是从栈顶弹出两个操作数),避免引入寄存器编号或复杂寻址逻辑,简化解释器实现。

性能影响很实际:栈顶缓存(TosCache)是 HotSpot 的关键优化,它把栈顶 1–2 个元素缓存在 CPU 寄存器里。一旦操作数栈深度超过缓存容量,就会触发内存读写,性能明显下降。

Ajelix
Ajelix

处理Excel和GoogleSheets表格的AI工具

下载
  • 每次方法调用前,JVM 根据 Code 属性中的 max_stack 值预分配栈空间,这个值由编译器静态分析得出,不是运行时伸缩的
  • dupswap 这类指令只操作栈顶有限几个元素,不会遍历整个栈 —— 所以它不是“栈”在数据结构意义上,而是“栈式访问协议”
  • 如果手写字节码或用 ASM 修改,max_stack 算小了,运行时抛 StackOverflowError(注意:不是 Java 层的 StackOverflowError,而是 JVM 启动时报错)

动态链接怎么实现“同一个方法调用,运行时指向不同实际目标”

动态链接不是在调用时才去查符号表,而是在类加载阶段就把符号引用(如 invokevirtual java/io/PrintStream.println:(I)V)解析成具体的方法入口地址,并存进运行时常量池的对应项中。但“解析时机”分两类:invokedynamic 是真·运行时绑定,其余指令在类初始化前就完成解析(前提是目标方法不被子类重写)。

容易踩的坑:当父类方法被子类重写,又用了 invokespecial(比如构造器、私有方法、super.xxx()),JVM 就绕过虚方法表,直接跳转到声明类型的方法体 —— 这就是为什么在构造器里调用可重写方法会出问题。

  • invokestaticinvokespecial 绑定目标在解析阶段就确定,属于“静态分派”
  • invokevirtualinvokeinterface 依赖对象实际类型 + 方法表(vtable / itable),是“动态分派”,但查找过程本身很快(现代 JVM 有内联缓存)
  • invokedynamic 的引导方法(bootstrap method)由用户代码控制,Lambda 表达式、字符串拼接等都靠它,首次调用慢,之后基本和普通调用一样快

局部变量表、操作数栈、动态链接三者如何配合完成一次方法调用

obj.foo(a, b) 为例:先将 obj 压入操作数栈(从局部变量表第 n 号槽取),再压入 ab;执行 invokevirtual 时,JVM 查 obj 的实际类的 vtable,找到 foo 入口;进入新栈帧后,局部变量表第 0 槽存 this(即 obj),第 1、2 槽依次存 ab;方法体内所有对参数的读写,都通过局部变量表索引完成,中间计算全走操作数栈。

关键细节常被忽略:局部变量表和操作数栈的数据不能跨栈帧共享。即使两个栈帧里都有同名变量,它们物理上完全隔离 —— 这也是为什么递归不会污染上层变量,但栈空间会耗尽。

  • 局部变量表负责“命名存储”,操作数栈负责“临时运算”,动态链接负责“目标定位”,三者分工明确,缺一不可
  • 逃逸分析可能让局部变量表里的对象直接分配在栈上(栈上分配),但这不影响局部变量表本身的结构和访问方式
  • GC Roots 包含当前栈帧的局部变量表中的 reference,所以只要变量还在表里(哪怕代码逻辑已不再使用),对象就不会被回收

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

590

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

105

2025.10.23

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1552

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1552

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1552

2023.10.24

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

551

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

214

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1552

2023.10.24

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

145

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号