学习JVM-基础篇-Java虚拟机栈&本地方法栈

Java虚拟机栈

Java虚拟机栈是JVM 为每个线程分配的私有内存区域,用于存储方法调用的上下文信息。每当线程调用一个 Java 方法时,JVM 会创建一个新的栈帧压入栈顶;方法执行完毕后,栈帧被弹出。栈采用先进后出(FILO)原则。

栈帧的结构

栈帧是栈的基本单位,每个方法调用对应一个栈帧。栈帧在方法开始时创建,在方法结束时销毁。包含的组件:

  • 局部变量表

    • 一个固定大小的数组,用于存储方法的参数和局部变量。索引从0开始,非静态方法的索引0存储this 引用,后续索引存储参数和局部变量。

    • 大小在编译时确定,由方法的字节码指令定义。例如,一个方法有3个参数和2个局部变量,局部变量表大小为5。

    • 存储基本数据类型(如int,boolean)和对象引用(reference类型)。基本类型占一个slot(槽位),long和double 占用两个slot。

  • 操作数栈

    • 一个先进后出的栈结构,用于执行字节码指令时的临时数据存储。例如,算术计算会从操作数栈弹出操作数,计算后压入结果。

    • 深度在编译时确定。字节码指令如iload (加载int)将值压入栈,istore 将值存储到局部变量表。

帧数据
  • 动态链接

    • 当前类的字节码指令引用了其他类的属性或者方法时,需要将符号引用(编号)转换成对应的运行时常量池中的内存地址。动态链接就保存了编号到运行时常量池的内存地址的映射关系。
  • 方法返回地址

    • 存储方法退出后应返回的指令地址。对于正常返回,JVM 使用此地址恢复执行;对于异常退出,JVM使用异常表处理。
  • 异常表

    • 异常表存放的是代码中异常的处理信息,包含了异常捕获的生效范围以及异常发生后跳转到的字节码指令位置。
栈内存溢出

Java虚拟机栈如果栈帧过多,占用内存超过内存可以分配的最大大小就会出现内存溢出。内存溢出报 StackOverflowError错误

如果我们不指定栈的大小,JVM将创建一个具有默认大小的栈。大小取决于操作系统和计算机的体系结构。

要修改 Java虚拟机栈的大小,可以使用虚拟机参数 -Xss

语法:-Xss 栈大小

单位:字节(默认,必须是1024倍数)、k或者K(KB)、m或者M(MB)、g或者G(GB)

例如:-Xss1048576 -Xss1024K

OutOfMemoryError:

  • JVM 允许动态扩展栈容量,但无法申请到足够内存(如系统内存耗尽)

  • 创建新线程时无法为栈分配初始内存(例如创建大量线程且 -Xss 设置过大,导致堆外内存不足)

本地方法栈

Java虚拟机栈存储了 Java 方法调用的栈帧,而本地方法栈存储的是native 本地方法的栈帧。

在 Hotspot 虚拟机中,Java虚拟机栈和本地方法栈实际上使用了同一个栈空间。本地方法栈用在内存上生成一个栈帧,临时保存方法的参数同时方便出现异常时也把本地方法的栈信息打印出来。

相关推荐
lifallen12 分钟前
edit-article:AI 味来自跳级
人工智能·学习·ai·ai编程·ai写作
淡海水26 分钟前
15-07-YooAsset面试篇-Unity性能优化与内存管理
java·unity·面试·性能优化·c#·游戏引擎
snow@li33 分钟前
Java:跨平台原理与JDK、JRE、JVM全景深度解析
java·开发语言·jvm
Livia要学习36 分钟前
Python闭包
开发语言·jvm·python
覆东流37 分钟前
2.Java程序基础
java·开发语言·后端
snow@li43 分钟前
SpringBoot:全套生命周期全景详解/应用级+Bean级
java·spring boot·rpc
xian_wwq1 小时前
【学习笔记】工具设计,Agent 的手比大脑更容易出问题-8/16
笔记·学习·agent
晴天161 小时前
Agent 全栈学习笔记 1-Day14
数据库·笔记·学习
love_muming1 小时前
二叉树操作全解析:从递归到层序遍历
java·数据结构·算法·二叉树
小的~~1 小时前
ThreadLocal 、InheritableThreadLocal 与 TransmittableThreadLocal 的进阶指南
java·开发语言