讲师中心 微信公众号
AI工具推荐 视频效率加速

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

星敏小哥_9292

星敏小哥_9292

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

|

999人浏览过

|

来源于php中文网

原创

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
bootstrap框架介绍
bootstrap框架介绍

本专题整合了bootstrap框架相关介绍,阅读专题下面的文章了解更多详细内容。

745

2026.03.18

bootstrap安装教程
bootstrap安装教程

本专题整合了bootstrap安装相关教程,阅读专题下面的文章了解更多详细操作教程。

199

2026.03.18

css中float用法
css中float用法

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

7107

2024.04.28

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

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

824

2025.10.23

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

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

6224

2023.10.24

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

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

6224

2023.10.24

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

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

6224

2023.10.24

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

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

1838

2023.08.03

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

100

2026.10.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
GDB Reference Card
GDB Reference Card

共0课时 | 0人学习

《Debugging with GDB》用户手册
《Debugging with GDB》用户手册

共0课时 | 0人学习

Valgrind FAQ
Valgrind FAQ

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn