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

相关推荐
mask哥9 小时前
力扣算法java实现汇总整理(上)
java·算法·leetcode
2301_8092047010 小时前
JavaScript中严格模式use-strict对引擎解析的辅助.txt
jvm·数据库·python
zjy2777711 小时前
mysql如何选择合适的索引类型_mysql索引设计实战
jvm·数据库·python
Aaswk11 小时前
Java Lambda 表达式与流处理
java·开发语言·python
是宇写的啊11 小时前
Spring AOP
java·spring
万邦科技Lafite11 小时前
京东item_get接口实战案例:实时商品价格监控全流程解析
java·开发语言·数据库·python·开放api·淘宝开放平台
Mr_pyx12 小时前
Spring AI 入门教程:Java开发者的AI应用捷径
java·人工智能·spring
冷小鱼12 小时前
JVM 异常崩溃排查全指南:从 Core Dump 到根因定位
jvm
爱上好庆祝13 小时前
学习js的第七天(wed APIs的开始)
前端·javascript·css·学习·html·css3
Zephyr_013 小时前
Leedcode算法题
java·算法