JVM内存区域-栈的理解

基本知识点

  • 栈 先进后出 LIFO的数据结构
  • 栈帧
    • 以线程为组,一个线程可能会创建多个栈帧
  • 栈帧的构成
    • 局部变量表
      • 编译期间确定其大小
      • 编译期间 存储在class文件的 该方法 对应的 方法表 的 CODE属性(表)中的 MAX_LOCAL属性中。
      • 如果方法是 实例方法,则局部变量表 第一个位置存储的是 this 引用
    • 操作数栈
      • 也是一个 LIFO的栈
      • 编译期间确定最大深度
      • 基本操作 就是将 局部变量表中的数据 根据class中的字节码指令不断地 入栈、出栈。
      • 单位:字宽, 一个字宽 代表32位的数据,可以存储java基本数据类型,包括double,long,他们占两个字宽。
    • 动态连接
      • 每个栈帧 都描述了一个方法,每个方法属于 一个 class文件,每个class拥有一个常量池,常量池中描述了很多 符号常量:比如 用户自定义的方法名,类名 等等。
      • 栈帧中 有一个引用,指向 被加载了的 class文件 (位于 java内存区域的 另外一个区域 :方法区中)中的 常量池。所谓动态连接,就是解析 当前栈帧中 出现的 符号引用(某个其他类的方法、或属性),将这个符号 引用变成 直接 引用的过程。
    • 方法返回地址
      • 方法退出 有两种方式
        • return 指令
        • 发生异常
      • 当遇到这两种情况时,结合程序计数器(一个线程私有的 内存区域 用于 记录 下一条 执行的字节码指令位于 class 中的地址。 ) 将当前 栈帧出栈,并切换到 下一个 栈帧。

通俗理解

  • 栈只是一个统称,其实我们真正需要了解的是栈帧。 栈帧是栈的基本结构,可以通俗的理解为,以线程为分组,一个线程每进入一个方法,就创建了一个栈帧,并将其压入栈中。

这里写图片描述

mainMethod(String args...)
{
    T r1 = method1(arg1,arg2);
    return r1; 
}

为了 方便理解 使用了 java 伪代码,其实 JVM执行的 是 编译后的 class 文件中的 字节码指令。

当一个线程进入到 mainMethod方法时,首先创建一个栈帧 并 将其入栈代表 mainMethod方法,逐行执行,发现调用method1时,保存好main栈帧的运行环境之后 创建新的栈帧代表 method1,然后将method1的栈帧入栈,通过method1的字节码指令,将位于栈帧中的局部变量表中 的arg1,arg2 ,依次压入 操作数栈, method1执行完毕后,通过method1栈帧记录的返回出口和程序计数器 查找到下一条 字节码指令,将计算结果 返回给 main 方法的,并将method1 栈帧 出栈,切换回 mainMethod的栈帧,并将计算结果 压入 mainMethod的 局部变量表的 r1变量中。

当然实际的情况远远比 这复杂的多,比如 栈帧之间 局部变量表 之间的共享等等,在这里只是做一个通俗的理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值