运行时数据区-虚拟机栈-局部变量表

栈中存储什么?

  • 每个线程都有自己的栈,栈中的数据都是以栈帧(Stack Frame)的格式存在
  • 在这个线程执行的时候每个方法各自对应一个栈帧
  • 栈帧是一块内存区块,是一个数据集,维系着方法在调用的过程中各种数据信息
  • JVM直接对Java栈的操作只有两个,就是对栈的压栈和出栈,遵循“先进后出”/“后进先出”原则
  • 在一条活动的线程中,一个时间点只会有一个活动的栈。即只有当前正在执行的方法的栈帧(栈顶栈帧)是有效的,这个栈被称为当前栈帧
  • 执行引擎运行所有字节码指令只对当前栈帧进行操作
  • 如果该方法调用了其他方法,对应新的栈帧就会被创建出来,放在栈的顶端,称为当前栈帧
  • 不同线程中所包含的栈帧是不允许相互引用的,即不可能在一个栈帧中引用另外一线程的栈帧
  • 如果当前方法调用了其他方法,方法返回之际,当前栈帧会回传此方法执行结果给前一个栈帧。接着,虚拟机会丢弃当前栈帧,使得点一个栈帧成为当前栈帧
  • Java方法有两种返回函数的方式,一种是正常函数的返回,使用return指令;另一种是抛出异常。不管使用哪种方式,都会导致栈帧的弹出

栈帧的内部结构

每个栈帧存储着:

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

局部变量表(Local Variables)

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

说明

(IEAD安转jclasslib插件就能查看)

  1. Name:说明该方法名字是main
  2. Descriptor:参数是一个String类型的一位数组([:表示数组,L表示该类型是引用类型,V:表示返回值是void)
  3. Access flags:修饰符是public

LocalVariables:可以看到main方法中有三个变量:args、localVariablesTest、num,在右边局部变量表中都有反应。

  1. index:表示参数索引位置
  2. Descriptor:描述参数类型
  3. Start PC:该值对应LineNamberTable中的对应关系就能知道变量在方法中作用域的起始位置

LineNumberTable:对应LocalVariable中的Start PC就能找出变量在方法中作用域起始的位置

Start PC为0时,对应的Line Number为6,我们在到LocalVariables中的Start PC为0的值。就能知道args的作用域是从java代码中的第6行开始。其余的两个参数也是如此。

非静态方法比静态方法的局部变量变中多个一个this变量(平时我们在非静态方法中可以通过this来获得当前对象的引用)

下图中的test方法,我们能看到在LocalVariable中有两个变量:this 和 i

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值