java内存地区 - 栈

打印 上一主题 下一主题

主题 1009|帖子 1009|积分 3027

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
java内存地区 - 栈

在JDK11中,JVM栈 (Java Virtual Machine Stack)是每个线程私有的内存地区,用于存储线程执行方法时的方法调用状态。JVM栈也称为Java捏造机栈,与线程的生命周期雷同。
以下是对Java捏造机栈的详细解析,包罗它的组成部分和存储内容:

1. Java捏造机栈的组成

Java捏造机栈由一个个**栈帧(Stack Frame)**组成。每次调用一个方法时,都会创建一个新的栈帧并压入JVM栈,方法执行完成后,栈帧会出栈。
一个栈帧包罗以下几个主要地区:

  • 局部变量表(Local Variable Table)
  • 操作数栈(Operand Stack)
  • 动态链接(Dynamic Linking,也叫方法引用)
  • 返回所在(Return Address)
  • 额外信息(Optional Data,如异常处理处罚状态)

2. 栈帧中的详细内容

2.1 局部变量表



  • 定义: 局部变量表是用来存储方法中的局部变量,包罗:

    • 方法的参数
    • 方法内部定义的局部变量

  • 存储内容:

    • 基本数据类型(如 int、float、long、double 等)
    • 引用类型(对象引用,如 String 的引用)
    • returnAddress 类型(指向字节码指令所在)

  • 特性:

    • 局部变量表的巨细在编译时确定,且在方法调用时分配。
    • 表的索引从 0 开始,方法的第一个参数通常存储在索引 0。

2.2 操作数栈



  • 定义: 操作数栈是一个后进先出(LIFO)的栈,用于方法执行中的中间运算和效果存储。
  • 存储内容:

    • 方法执行过程中必要操作的中间数据(如加法操作中的两个操作数)。
    • 方法调用的参数(当调用其他方法时)。

  • 特性:

    • 字节码指令直接对操作数栈举行操作,比如 iadd 用于弹出两个整数值相加并将效果压入栈。

2.3 动态链接



  • 定义: 动态链接存储的是方法调用过程中的符号引用,这些符号引用在运行时被解析为详细的方法或字段的直接引用。
  • 作用:

    • 支持方法调用的动态绑定,尤其是多态。
    • 通过运行时常量池解析相干符号。

2.4 方法返回所在



  • 定义: 返回所在用于存储方法调用完成后,必要返回的步伐计数器(PC)位置。
  • 特性:

    • 如果当前方法是通过字节码指令调用的,返回所在会指向调用指令的下一条指令。
    • 如果方法调用是通过其他方式(如异常),返回所在可能为空。

2.5 附加信息



  • 定义: 栈帧可能还包罗一些与方法执行相干的附加信息,如:

    • 异常处理处罚表
    • 调试信息


3. JVM栈的生命周期



  • 每个线程创建时,Java捏造机栈被分配。
  • Java捏造机栈的每个栈帧对应一个方法调用,随着方法调用的嵌套,栈帧逐步压入栈中。
  • 每一个方法冲开始调用到执行竣事的过程,都对应这一个栈帧的入栈出栈的过程。
  • 当方法返回或异常停止时,栈帧出栈。
  • 如果栈深度凌驾答应的最大值(如无限递归),会抛出 StackOverflowError。
  • 如果内存不敷以为新栈帧分配空间,会抛出 OutOfMemoryError。

4. 示例解析 - 运行时的栈帧分布

以下是一个简单的代码示例,以及在JVM栈中的体现:
  1. public class Test {
  2.     public static void main(String[] args) {
  3.         int a = 5;
  4.         int b = 10;
  5.         int sum = add(a, b);
  6.     }
  7.     public static int add(int x, int y) {
  8.         return x + y;
  9.     }
  10. }
复制代码

  • main 方法调用:

    • 局部变量表:

      • args:存储数组引用
      • a:5
      • b:10
      • sum:等候存储 add 方法返回的效果

    • 操作数栈:

      • 调用 add 方法时,将 a 和 b 压入操作数栈。


  • add 方法调用:

    • 局部变量表:

      • x:存储值 5
      • y:存储值 10

    • 操作数栈:

      • 执行 x + y 时,先将 x 和 y 压入栈,再弹出举行加法操作。


  • 返回:

    • add 方法将效果压入操作数栈,并返回给 main 方法的 sum 变量。


5. 栈中的异常



  • StackOverflowError:

    • 发生在栈的深度凌驾捏造机答应的最大值时,比方递归调用过深。

  • OutOfMemoryError:

    • 如果JVM栈内存答应动态扩展,当扩展栈容量无法申请到充足内存时, 无法为新的栈帧分配内存时触发。

  • 留意: 《Java捏造机规范》明确答应Java捏造机实现自行选择是否支持站的动态扩展,而Hotspot(jdk1.2及之后的默认捏造机)的选择是不支持扩展,以是jdk1.2之后,除非在创建线程申请内存时就因为无法获得充足的内存而触发OutOfMemoryError异常,否则在线程运行时是不会因为扩展而导致内存的溢出的,只会因为栈容量无法容纳新的栈帧而导致StackOverflowError异常(此段摘自《深入明确Java捏造机》 第第三版中)

6.栈配置



  • -Xss<size>

    • 用于设置每个线程栈的巨细。
    • 参数格式为:

      • <size> 指定巨细,可以用单位 k 或 m 表现(如 -Xss512k 或 -Xss1m)。
      • 默认值依赖于操作体系和JVM实现,通常为 1 MB 或 512 KB。

    • 影响每个线程的栈深度,但总栈巨细受限于体系内存和线程数。


7.本地方法栈



  • 本地方法栈(Natice Method Stacks) 与Java捏造机栈所发挥的作用时非常相似的,其区别只是Java捏造机栈为捏造机执行java方法(也就是字节码)服务,而本地方法栈则是为了捏造机使用到的本地(native)方法服务。HotSpot捏造机(Java默认的捏造机)直接把本地方法栈和捏造机栈合二为一了。

总结:
JVM栈的核心在于管理方法调用和执行,每个栈帧包罗局部变量表、操作数栈、动态链接、返回所在等。栈的合理设计是 Java 步伐高效运行的底子,同时必要留意栈的溢出题目。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

没腿的鸟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表