当前位置: 首页 > article >正文

JVM规范之栈帧

JVM规范之栈帧

  • 前言
  • 正文
    • 概述
    • 局部变量表
    • 操作数栈
    • 动态链接
  • 总结
  • 参考链接

前言

上一篇文章了解了JVM规范中的运行时数据区:
JVM规范之运行时数据区域
其中,栈是JVM线程私有的内存区,栈中存储的单位是帧(frames),本篇文章通过JVM8规范学习栈帧在JVM运行时的作用。

正文

概述

每个栈帧的内存分配自线程私有的 Java 虚拟机栈(JVM Stack),线程调用方法时压栈,方法结束时出栈销毁。

帧的作用是保存方法调用的局部变量、中间结果、执行动态链接、方法返回信息、发送异常。一个帧通常包含局部变量表、操作数栈、运行时常量池引用,这些组件都是帧私有的。

创建/销毁时机:
当方法被调用的时候,栈帧也会被创建,当方法调用完成时,栈帧被销毁,方法调用的含义包含两种:

  • 方法正常调用结束,方法运行期间,JVM 没有抛出或者没有显式地使用throw抛出未被捕获的异常;
  • 方法非正常结束(如抛出未捕获异常)时,栈帧会提前销毁,JVM 通过异常栈轨迹(StackTrace)记录各层栈帧信息,用于调试;

内存分配策略:
局部变量表和操作数栈的大小在编译时确定,运行时常量池引用的大小本质是一个指针,具体大小可能取决于具体的 JVM 实现,因此栈帧的大小由编译时确定的局部变量表和操作数栈的理论最大值,结合 JVM 实现的内存布局(如 Slot 字节数、对齐策略)决定。

局部变量表

  • 每个栈帧都有自己的局部变量表,局部变量表的大小是在编译时确定的,因此在运行时可以一次性从栈上进行分配;
  • 局部变量表通过索引的方式访问,每个索引的位置可以理解一个变量槽(slot),每个槽可以存储boolean, byte, char, short, int, float, reference, returnAddress类型的值,一对slot可以存储longdouble类型的值;
  • longdouble占用两个连续的变量槽,比如一个long占用了索引nn+1两个变量槽的位置,但是n+1位置是不可读取的,可以被写入,这会导致变量槽n位置的数据失效;
  • JVM 规范没有限制局部变量表中的数据必须进行字节对齐;
  • 在调用方法时,JVM 使用局部变量表传递参数,从索引位置 0 开始,如果调用的方法是一个实例方法,索引 0 位置总是被传入this;对于静态方法,局部变量表索引 0 不存储this,直接从索引 0 开始存储方法参数。

操作数栈

  • 每个栈帧都包含一个操作数栈,栈的最大深度是编译时确定的,当栈帧被创建时,操作数栈是空的;
  • 操作数栈符合栈的特点,LIFO,操作数栈中每个entry可以容纳一个JVM数据类型,包含longdouble类型;
  • 操作数栈中存储的数据类型和操作指令必须严格匹配,JVM会在进行class文件验证时,检查操作数栈的使用是否符合规范;
  • 操作数栈中,long/double作为 64 位值,占用 2 个深度单位,其他类型占 1 个;

动态链接

什么是动态链接?
在 JVM 中,动态链接类加载机制运行时环境的关键环节,主要用于将符号引用(Symbolic References)解析为直接引用(Direct References),是实现多态的核心技术。

  • 每个栈帧都包含一个运行时常量池的引用,用于实现方法调用的动态链接过程;
  • 字节码文件中描述了方法调用的符号表引用,但是并没有实际代码的内存地址,因此动态链接是将符号表引用翻译为直接引用;
  • 动态链接是实现多态的核心机制,通过运行时常量池解析虚方法的符号引用,在运行时根据对象实际类型(如instanceof)找到具体方法的直接引用。例如,子类重写父类方法时,编译期符号引用指向父类,运行时动态链接到子类实现。

补充:

  • 在编译阶段,字节码文件中仅保存符号表引用,不会涉及静态链接或者动态链接的过程;
  • 静态链接在类加载阶段(解析阶段)确定方法调用目标,将符号表引用转化为直接引用,而动态链接指JVM在运行时才能确定调用目标的实例类型,在运行时将符号表引用转化为直接引用。

动态链接代码示例

public class Animal {public void sound() {System.out.println("Animal"); } // 虚方法
}
public class Dog extends Animal {@Overridepublic void sound() {System.out.println("Woof");} // 动态链接目标
}
// 调用时通过运行时常量池解析为Dog.sound()
Animal animal = new Dog();
animal.sound(); // invokevirtual指令触发动态链接

总结

本篇文章根据JVM 8规范了解了栈帧的数据结构:

  • 栈帧是在JVM线程进行方法调用时创建,每调用一个方法就会创建一个栈帧,每当方法调用结束或者异常结束,栈帧会被出栈;
  • 每个栈帧通常包含局部变量表、操作数栈、运行时常量池引用,栈帧的内存占用大小仅取决于JVM的实现,其中,局部变量表类似一个数组,JVM线程通过索引的方式读取局部变量表的内容;操作数栈用于保存中间结果和方法保存结果,要求操作数栈中的数据类型和指令必须匹配;运行时常量池引用是JVM实现动态链接的关键,当然也用来支持类字段引用和其它常量的访问;

JVM 规范仅定义栈帧的逻辑结构(如局部变量表、操作数栈),具体实现(如 Slot 是否对齐、指针压缩)由厂商决定。例如,HotSpot 中 Slot 通常为 32 位,long/double占 2 个 Slot,无需 64 位对齐。

参考链接

jvm8s

相关文章:

JVM规范之栈帧

JVM规范之栈帧 前言正文概述局部变量表操作数栈动态链接 总结参考链接 前言 上一篇文章了解了JVM规范中的运行时数据区: JVM规范之运行时数据区域 其中,栈是JVM线程私有的内存区,栈中存储的单位是帧(frames)&#xff…...

【C++指南】string(四):编码

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《C指南》 期待您的关注 引言 在 C 编程中,处理字符串是一项极为常见的任务。而理解字符串在底层是如何编码存储的&…...

深度学习之序列建模的核心技术:LSTM架构深度解析与优化策略

LSTM深度解析 一、引言 在深度学习领域,循环神经网络(RNN)在处理序列数据方面具有独特的优势,例如语音识别、自然语言处理等任务。然而,传统的 RNN 在处理长序列数据时面临着严重的梯度消失问题,这使得网…...

AI量化交易是什么?它是如何重塑金融世界的?

第一章:证券交易的进化之路 1.1 从喊价到代码:交易方式的革命性转变 在电子交易普及之前,证券交易依赖于交易所内的公开喊价系统。交易员通过手势、喊话甚至身体语言传递买卖信息,这种模式虽然直观,但效率低下且容易…...

分布式事务处理方案

1. 使用Seata框架解决 1.1 XA 事务 1.1.1 XA整体流程 第一阶段 RM1开启XA事务-> 执行业务SQL -> 上报TC执行结果RM2开启XA事务-> 执行业务SQL -> 上报TC执行结果 第二阶段 TC根据 RM上报结果通知RM一起提交/回滚XA事务 1.1.2 XA特点 XA 模式必须要有数据库的支…...

CVE-2024-36467 Zabbix权限提升

漏洞描述 在Zabbix中,具有API访问权限的已认证用户(例如具有默认用户角色的用户)可以通过调用user.update API接口,将自己添加到任何用户组(如Zabbix管理员组)。然而,用户无法添加到已被禁用或…...

Dify中的自定义模型插件开发例子:以xinference为例

本文使用Dify v1.0.0-beta.1版本。模型插件结构基本是模型供应商(模型公司,比如siliconflow、xinference)- 模型分类(模型类型,比如llm、rerank、speech2text、text_embedding、tts)- 具体模型(…...

crud方法命名示例

以下是基于表名dste_project_indicator(项目指标表)的完整命名示例,覆盖各类增删改查场景: 1. 表名与实体类映射 // 表名:dste_project_indicator // 实体类:DsteProjectIndicatorEntity public class Ds…...

尚硅谷redis7 33-36 redis持久化之RDB优缺点及数据丢失案例

官网说明优点: RDB是Redis数据的一个非常紧凑的单文件时间点表示,RDB文件非常适合备份。例如,您可能希望在最近的24小时内每小时旧档一次RDB文件,并在30天内每天保存一个RDB快照,这使您可以在发生来难时轻松恢复不同版本的数据集。RDB非常适合灾难恢复,它是一个可以…...

No such file or directory: ‘ffprobe‘

目录 详细信息: 解决方法: No such file or directory: ffprobe 详细信息: File "/usr/local/lib/python3.10/dist-packages/framepump/framepump.py", line 168, in get_duration return float(ffmpeg.probe(video_path)[form…...

计算机网络-WebSocket/DNS/Cookie/Session/Token/Jwt/Nginx

文章目录 WebSocketDNS什么是dns域名解析底层协议 cookie/sessionToken/JWTNginx WebSocket 一种网络通信协议,允许在单个 TCP(半双工) 连接上进行全双工通信(客户端和服务器可同时双向传输数据)。 HTTP是基于请求-响…...

功能“递归模式”在 C# 7.3 中不可用,请使用 8.0 或更高的语言版本的一种兼容处理方案

原程序: internal class ControllerParameterCreator : IParameterCreator {private Controller controller;public ControllerParameterCreator(Controller controller){this.controller controller;}public Parameter CreateSystem(string name, int unused){re…...

第4章-操作系统知识

存储管理 固定分区:一种静态分区方式请求分页存储管理覆盖技术:覆盖技术是指让作业中不同时运行的程序模块共同使用同一主存区域。...

将网页带格式转化为PDF

# 一、安装插件 SingleFile | 将完整的页面保存到一个 HTML 文件中 – 下载 🦊 Firefox 扩展(zh-CN) 打开火狐浏览器,安装上面的插件 # 二、下载html单文件 打开对应的网页,点击插件下载对应的html文件 # 三、打开…...

【ArcGIS】ArcGIS AI 助手----复现

github地址 korporalK/Archer-GIS-AI-Assitant:Archer 在 ArcGIS Pro 中将自然语言命令转换为自动化 GIS 工作流。它使用代理框架(计划-验证-执行)构建并由 LLM 提供支持,可简化空间分析、减少手动工作并使 GIS 更易于访问。Arch…...

使用 FFmpeg 将视频转换为高质量 GIF(保留原始尺寸和帧率)

在制作教程动图、产品展示、前端 UI 演示等场景中,我们经常需要将视频转换为体积合适且清晰的 GIF 动图。本文将详细介绍如何使用 FFmpeg 工具将视频转为高质量 GIF,包括: ✅ 保留原视频尺寸或自定义缩放✅ 保留原始帧率或自定义帧率✅ 使用调色板优化色彩质量✅ 降低体积同…...

《Java vs Go vs C++ vs C:四门编程语言的深度对比》

引言​​ 从底层硬件操作到云端分布式系统,Java、Go、C 和 C 四门语言各自占据不同生态位。本文从​​设计哲学​​、​​语法范式​​、​​性能特性​​、​​应用场景​​等维度进行对比,为开发者提供技术选型参考。 一、​​设计哲学与历史定位​​…...

充电枪IEC62196/EN 62196测试内容

充电枪IEC62196/EN 62196测试内容 一、机械性能测试 插拔力测试 交流充电接口的插入/拔出力需≤100N,直流接口≤140N。若使用助力装置,操作力仍需满足上述要求。 测试方法:通过弹簧秤或专用试验机(如Sun-CB设备)测…...

有效的字母异位符--LeetCode

题目 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true示例 2: 输入: s "rat", t "car" 输出: false 思路一:排序 t 是 s …...

SAP ERP 系统拆分的七大挑战

在企业变革或管理运营风险时,剥离IT系统能带来显著效益,但SAP ERP系统的复杂性使得这项工作充满挑战。如果管理不当,可能会导致数据不一致、运营中断、合规风险和意外成本。由于SAP ERP系统深度集成于企业核心业务流程中,其拆分工…...

AcrelEMS 3.0智慧能源管理平台:构建企业微电网数智化中枢

安科瑞电气顾强 在"双碳"目标驱动下,企业能源管理正从粗放式运营向精细化、智能化转型。AcrelEMS 3.0智慧能源管理平台以微电网为核心载体,通过"感知-分析-决策-控制"的全链路数字化能力,助力工商企业、医疗机构、教育机…...

【HTML-12】HTML表格常用属性详解:从基础到高级应用

表格是HTML中最强大且常用的元素之一,它能够以结构化的方式展示数据。本文将全面介绍HTML表格的常用属性,帮助您创建美观、响应式且语义化的数据表格。 1. HTML表格基础结构 在深入了解属性之前,我们先回顾一下HTML表格的基本结构&#xff…...

Word转PDF--自动生成目录

1-Word文档中已经包含自动生成的目录; 2-选择“文件”; 3-另存为,PDF; 4-选择“选项”按钮,在弹出的窗口中,勾选“创建书签时使用标题”。...

MySQL组合索引优化策略

优化MySQL组合索引需要综合考虑查询模式、索引结构及数据库特性。以下是关键优化策略及示例: 1. 遵循最左前缀原则 策略:确保查询条件包含组合索引最左侧列。示例:索引(a,b,c)生效场景:WHERE a1 AND b2 -- ✔️ 使用a和b W…...

Spring MVC 的的核心原理与实践指南

一、Spring MVC 概述 Spring MVC 是 Spring 框架中的一个重要模块,用于构建基于 Java 的 Web 应用程序。它遵循模型-视图-控制器(MVC)设计模式,提供了一种结构化的方式来开发灵活、松耦合的 Web 应用。 Spring MVC 的特点&#xf…...

轻量级视觉语言模型 Dolphin:高效精准的文档结构化解析利器

在数字化办公和学术研究日益普及的今天,如何高效、准确地处理各类文档图像成为了一个亟需解决的问题。Dolphin 应运而生,作为一款基于异构锚点提示的多模态文档图像解析模型,它不仅打破了传统手动整理文档的繁琐流程,更以远超主流…...

如何安全配置数据库(MySQL/PostgreSQL/MongoDB)

数据库是许多应用程序的核心组成部分,因此保护数据库的安全性至关重要。无论是MySQL、PostgreSQL还是MongoDB,都需要经过适当的安全配置才能防止潜在的安全威胁。本文将介绍如何安全配置这些流行的数据库管理系统,以确保数据的保密性、完整性…...

将 Docker 镜像从服务器A迁移到服务器B的方法

在日常工作中,我们有时会需要将服务器 A上的镜像上传至服务器B上,下面给出具体操作方式,以镜像 postgres:15 为例进行讲解。 首先在服务器A上拉取 镜像 postgres:15 ,命令如下: docker pull postgres:15下面再将服务…...

git merge解冲突后,add、continue提交

git merge解冲突后,add、continue提交 git merge操作冲突后,需要手动解冲突,解完冲突后,需要: git add . 然后,进入一般的正常git代码提交流程。 git合并‘merge’其他分支的个别文件到当前branch_gitbash 合并branc…...

Lines of Thought in Large Language Models

Lines of Thought in Large Language Models 《Lines of Thought in Large Language Models》(大语言模型中的思维链)聚焦于分析大语言模型(LLMs)在生成文本时,其内部向量轨迹的统计特性。 核心目标是揭示LLMs复杂的“思维过程”(即文本生成时的隐藏状态变化)能否被简…...