每个栈帧中包含:

  • 局部变量表(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. C++ Templates (1.1 初窥函数模板 A First Look at Function Templates)

    返回完整目录 目录 1.1 初窥函数模板 A First Look at Function Templates 1.1.1 定义模板 Defining the Template 1.1.2 使用模板 ...

  2. linux下top命令详细介绍

    linux下top命令详细介绍 top 命令是 Linux 下常用的系统资源占用查看及性能分析工具,能够实时显示系统中各个进程的资源(比如cpu.内存的使用)占用状况,top命令的执行结果是一个动态显 ...

  3. 客户端操作 2 HDFS的API操作 3 HDFS的I/O流操作

    2 HDFS的API操作 2.1 HDFS文件上传(测试参数优先级) 1.编写源代码 // 文件上传 @Test public void testPut() throws Exception { Co ...

  4. Windows中使用PowerShell查看和卸载补丁

    查看:get-hotfix -id KB4470788 卸载:wusa /uninstall /kb:3045999 get-hotfix -id KB4470788 wusa /uninstall ...

  5. Shell编程—控制脚本

    1处理信号 1.1信号表 编号 信号名称 缺省操作 解释 1 SIGHUP Terminate 挂起控制终端或进程 2 SIGINT Terminate 来自键盘的中断 3 SIGQUIT Dump ...

  6. 牛客网数据库SQL实战解析(1-10题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  7. 【python】装饰器听了N次也没印象,读完这篇你就懂了

    装饰器其实一直是我的一个"老大难".这个知识点就放在那,但是拖延症... 其实在平常写写脚本的过程中,这个知识点你可能用到不多 但在面试的时候,这可是一个高频问题. 一.什么是装饰 ...

  8. 【Webpack】NodeJS + Webpack

    目的:想要通过npm命令按照我们的规则生成静态资源(webpack4以后还能做到很多性能优化的配置,我所知道的只有css.js分包,以达到资源快速加载快速呈现的效果). 一.安装webpack npm ...

  9. Python程序结构

    Python程序结构 分支结构 条件语句: if 判断: .....满足判断条件执行的代码块 else: .....不满足判断条件执行的代码块 if 判断1: .....满足判断条件1执行的代码块 e ...

  10. js转换人民币金额 小写到大写

    u.bigNum=function(n) { var fraction = ['角', '分']; var digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒 ...