学习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虚拟机栈和本地方法栈实际上使用了同一个栈空间。本地方法栈用在内存上生成一个栈帧,临时保存方法的参数同时方便出现异常时也把本地方法的栈信息打印出来。

相关推荐
C+-C资深大佬19 小时前
Java 变量:从入门到精通
java·开发语言·python
辞旧 lekkk19 小时前
【Qt系统相关】鼠标事件
linux·开发语言·qt·学习·计算机外设·萌新
Flittly19 小时前
【日常小问】Docker 部署 Nacos 2.4.3,Dubbo 3.3 连接 Config Service 失败排查
java·spring boot·dubbo
不爱编程的小陈19 小时前
操作系统内存管理 —— 虚拟内存
jvm
kuonyuma20 小时前
java之动态代理
java·开发语言
衔烛之龙120 小时前
Windows x64 构建 liboqs-java教程
java·windows·python
子非鱼942720 小时前
10-Flutter调用鸿蒙原生能力前置课:MethodChannel和PlatformView准备
学习·flutter·华为·harmonyos
小L~~~20 小时前
MLIR学习笔记
笔记·学习·mlir
一路向北North20 小时前
Spring Security OAuth2.0(20):完善环境配置
java·后端·spring
Java面试题总结20 小时前
IntelliJ IDEA 从卡顿到起飞,只用改这些。。。
java·ide·intellij-idea