每个栈帧中包含:

  • 局部变量表(Local Variables)
  • 操作数栈(Opreand Stack) 或表达式栈
  • 动态链接 (Dynamic Linking) (或指向运行时常量的方法引用)
  • 动态返回地址(Return Address) (或方法正常退出或者异常退出的引用的定义)
  • 一些附加信息

局部变量表

  • 局部变量表也被称之为局部变量数据组或本地变量表
  • 定义为一个数字数组,主要用户存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用(reference),以及returnAddress 类型
  • 由于局部变量表示建立在线程的栈上,是线程的私有数据,因此不存在数据安全问题
  • 局部变量表所需要的容量大小是在编译期确定下来的,并保存在方法的Code属性的maximun local variables数据项中,在方法运行期间时不会改变局部变量表的大小的
  • 方法嵌套调用的次数由栈的大小决定,一般来说,栈越大,方法嵌套调用次数越多,对于一个函数而言,他的参数和局部变量越多,使得局部变量表膨胀,它的栈就越大,以满足方法调用所需传递的信息增大的需求,进而函数调用就会占更多的栈空间,导致其嵌套调用次数就会减少
  • 局部变量表中的变量只在当前方法调用中有效。在方法执行时,虚拟机通过使用局部变量表完成参数值到参数变量列表的传递过程,当方法调用结束后,随着方法栈的销毁,局部变量表也会随之销毁

局部变量表的存储单元Slot(变量槽)

  • 参数值的存放总是在局部变量数据的index0开始,到数组长度-1的索引结束
  • 局部变量表,最基本的存储单元是Slot(变量槽)
  • 局部变量表中存放编译期可知的各种基本数据类型(8种)、引用类型(reference)、returnAdderss类型的变量
  • 在局部变量表中,32位以内的类型只占一个slot(包括returnAdderss类型)64位的类型(long和double)占用两个slot

    • byte、short、char在存储前被转换为int,boolean也被准换为int,0为false,1为true
    • long和double则占据两个slot
  • JVM会为局部变量表中的每一个slot都分配一个访问索引,通过这个索引即可成功的访问到局部变量表中指定的局部变量值
  • 当一个实例方法被调用的时候,它的方法参数和方法体内部定义的局部变量表将会按照顺序被复制到局部变量表中的每一个slot上
  • 如果需要访问局部变量表中一个64bit的局部变量值时,只需要使用前一个索引即可
  • 如果当前帧是由构造方法或者实例方法创建的,那么该对象引用this将会被存放在index为0的slot处,其余的参数按照参数表顺序继续排列

各个类型占用slot图示

  • slot也是可以进行重复利用的,即如果一个局部变量过了其作用域,那么在其作用域之后申明的新的局部变量就很有可能会复用过期的局部变量的槽位,从而达到节约资源的目的。主要的运用方式如下所示,其中{}外作用域就结束了
    //出了大括号就不能用了
public void LocalVar(){
{
int a= 0;
System.out.println(a);
}
//此时b就会复用a的槽位
int b=0;
}

常见问题

Q:为什么static中不能调用this方法

A:因为this的索引只存在构造方法和实例方法的局部变量表中,而static是在初始化方法<clinit>中进行初始化的,里面没有保存this变量的索引

Q:变量的分类

A:

    • 按照数据类型分类

      • 基本数据类型
      • 引用数据类型(对象)
    • 按照在类中的位置分类
      • 成员变量:类中变量,在使用前,都经历默认初始化赋值

        • 类变量,Linking的prepare阶段,给类变量默认赋值–>initial阶段,给类变量显示赋值,即静态代码块赋值
        • 实例变量,随着对象的创建,会在堆空间中分配实例变量空间,并进行默认赋值
      • 局部变量:方法中的变量。在使用时必须进行显示的赋值,否则编译不通过

Q:局部变量与成员变量的对比

A:

    • 参数表分配完毕以后,在根据方法体内定义的变量的顺序和作用域分配
    • 我们知道类变量表有两次初始化的机会,第一次是在“准备阶段”,执行系统初始化,对类变量设置零值,另一次是在“初始化”阶段,赋予变量在代码中定义的初始值
    • 和类变量初始化不同的是,局部变量表不存在系统初始化过程中,这就意味着一旦定了局部变量则必须认为的初始化,否则无法使用
public void test(){
int i;
Systme.out.println(i);
//这种是编译不通过的
}

其他

  • 在栈帧中,与性能调优关系最为密切的部分就是前面提到的局部变量表,在方法执行时,虚拟机使用局部变量表完成方法的传递
  • 局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中的直接或者间接引用的对象都不会被回收
  • 也可以新建局部对象

附:JVM学习目录

栈帧的内部结构--局部变量表(Local Variables)的更多相关文章

  1. 栈帧的内部结构--操作数栈(Opreand Stack)

    每个栈帧中包含: 局部变量表(Local Variables) 操作数栈(Opreand Stack) 或表达式栈 动态链接 (Dynamic Linking) (或指向运行时常量的方法引用) 动态返 ...

  2. 栈帧的内部结构--动态链接 (Dynamic Linking)

    每个栈帧中包含: 局部变量表(Local Variables) 操作数栈(Opreand Stack) 或表达式栈 动态链接 (Dynamic Linking) (或指向运行时常量的方法引用) 动态返 ...

  3. 栈帧的内部结构--动态返回地址(Return Address)

    每个栈帧中包含: 局部变量表(Local Variables) 操作数栈(Opreand Stack) 或表达式栈 动态链接 (Dynamic Linking) (或指向运行时常量的方法引用) 动态返 ...

  4. JVM-栈帧之局部变量表

    1.栈帧的内部结构 每个栈帧中存储着: 局部变量表(Local Variables) 操作数栈(Operand Stack)(或表达式栈) 动态链接(Dynamic Linking)(或指向运行时常量 ...

  5. 从 i++ 和 ++i 说起局部变量表和操作数栈

    本文转载自:从 i++ 和 ++i 说起局部变量表和操作数栈 最近公司有人看了尚硅谷柴林燕老师的第一季面试题,就想来考考我.我觉得柴老师讲的很好,部分内容可以延伸一下,所以写这篇文章分享给大家! 这篇 ...

  6. Java虚拟机栈--栈帧

    栈帧的内部结构 每个栈帧中存储着 1.局部变量表(Local Variables) 2.操作数栈(Operand Stack)(或表达式栈) 3.动态链接(Dynamic Linking)(或执行&q ...

  7. 2.Jvm 虚拟机栈和栈帧

    Jvm 虚拟机栈和栈帧 1.栈帧(frames) 官网描述 A frame is used to store data and partial results, as well as to perfo ...

  8. 详细解析Java虚拟机的栈帧结构

    欢迎关注微信公众号:万猫学社,每周一分享Java技术干货. 什么是栈帧? 正如大家所了解的,Java虚拟机的内存区域被划分为程序计数器.虚拟机栈.本地方法栈.堆和方法区.(什么?你还不知道,赶紧去看看 ...

  9. 深入理解java虚拟机(十) Java 虚拟机运行时栈帧结构

    运行时栈帧结构 栈帧(Stack Frame) 是用于虚拟机执行时方法调用和方法执行时的数据结构,它是虚拟栈数据区的组成元素.每一个方法从调用到方法返回都对应着一个栈帧入栈出栈的过程. 每一个栈帧在编 ...

随机推荐

  1. 可爱的python

    可爱的python 作者:  哲思社区出版社: 电子工业出版社 优点 1. 案列讲解很详细,前几章的内容恰好是我想要了解的,例如利用python os模块读取磁盘的文件,或者获得文字的编码方式.这些内 ...

  2. jenkins,开源CI工具

    目前最热门CI工具的jenkins,学习笔记: 一.jenkins如何实现执行命令 1.执行jenkins同主机上的命令

  3. DOM 事件机制&事件委托

    一.事件机制 事件是在编程时系统内发生的动作或者发生的事情,系统会在事件出现的时候触发某种信号并且会提供一个自动加载某种动作的机制(来自MDN).每个事件都有事件处理器(有时也叫事件监听器),也就是触 ...

  4. 接口测试 Mock 实战 | 结合 jq 完成批量化的手工 Mock

    本文霍格沃兹测试学院学员学习实践笔记. 一.应用背景 因为本章的内容是使用jq工具配合完成,因此在开始部分会先花一定的篇幅介绍jq机器使用,如果读者已经熟悉jq,可以直接跳过这部分. 先来看应用场景, ...

  5. centos 7 对用过yum更新的软件服务进行降级

    centos 7 执行 yum update 会对现有服务软件进行更新,但是如果把不该升级的软件升级,彼此软件不兼容,如何进行降级,比如:kibana 必须与 elasticsearch 大版本相同, ...

  6. e3mall商城的归纳总结3之后台商品节点、认识nginx

    一  后台商品节点 大家都知道后台创建商品的时候需要选择商品的分类,而这个商品的分类就就像一棵树一样,一层包含一层又包含一层.因此这里用的框架是easyUiTree.该分类前端使用的是异步加载模式(指 ...

  7. Python3 高级编程技巧(部分)

    目录: 在列表.字典.集合中筛选数据 为元组元素命名 通过列表.元组创建字典 字典排序 寻找字典的公共键 让字典保持有序 生成器函数 yield协程 同时遍历值与下标 在列表.字典.集合中筛选数据 很 ...

  8. php验证当前是设备是电脑端还是手机端

    <?php // 验证设备为PC还是WAP $agent = $_SERVER['HTTP_USER_AGENT']; if(strpos($agent,"comFront" ...

  9. JAVA集合类简要笔记 - 内部类 包装类 Object类 String类 BigDecimal类 system类

    常用类 内部类 成员内部类.静态内部类.局部内部类.匿名内部类 概念:在一个类的内部再定义一个完整的类 特点: 编译之后可生成独立的字节码文件 内部类可直接访问外部类私有成员,而不破坏封装 可为外部类 ...

  10. java初探(1)之秒杀项目总结

    在开始总结之前,先记录一个刚看到的博客,编程规约.该博客记录了一些java开发上的规范,可以在编码的时候引入这些规范. 无论流行框架一直怎么改变,web开发中的三层架构一直属于理论的基础存在. 表现层 ...