栈帧是Java虚拟机栈的结构,每个栈帧都有自己的局部变量表、操作数栈、动态链接和方法返回地址等信息,还允许携带与JVM实现相关的附加信息,如,对程序调试提供支持的信息。

1 局部变量表

  局部变量表存储基本数据类型(8种)、对象引用、returnAddress类型。以变量槽Slot为最小单位,一个Slot可以存放一个32位以内的数据类型,因此,long和double需要两个Slot来保存。栈帧采用较小的索引值来定位,例如,double类型的索引值为n,实际上用了索引值n和n+1两个局部变量来存储这个值,访问的时候,通过索引值n来定位这个double类型。

  Java虚拟机使用局部变量表来完成方法调用时的参数传递。当调用类方法(静态类方法)时,参数依次传递到局部变量表从0开始的连续位置上。当调用实例方法(new)时,第0个局部变量一定用来存储该实例方法所在对象的引用(this关键字)。

  为节省空间,Slot是可以重用的,当PC计数器的值超过了某个变量的作用域,那这个变量对应的Slot就可以交给其他变量使用。不过这样的设计也会引起副作用,比如它会影响到GC行为。如下问题:

问题:通过设置null可以表示对象可回收?

  这种操作可做为极其特殊情况下的奇技(对象占用内存大、此方法的栈帧长时间不能被回收,方法调用次数达不到JIT的编译条件)。而通常经过JIT编译优化后会消除掉null的赋值操作,所以一般不需要赋值null。

long和double的非原子协定

  对于64位的数据类型,JMM定义了一条相对宽松的规定:允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位的操作来进行,即允许虚拟机实现选择可以不保证64位数据类型的load、store、read、write操作的原子性,这就是long和double的非原子性协定。

  也就是说,如果有多个线程共享一个未声明为volatile的long或double的变量,并且同时对它们进行读取和修改操作,那么某些线程可能会读取到一个既非原值,也不是其他线程修改值的代表了“半个变量”的数值。

  不过目前商用虚拟机几乎都选择把64位数据的读写操作作为原子操作来对待,因此编写代码时一般不需要把用到的long和double专门声明为volatile。

2 操作数栈

  栈帧在刚刚创建时,操作数栈是空的。Java虚拟机提供一些字节码指令来从局部变量表或者对象实例的字段中复制常量或变量值到操作数栈中,也提供了一些指令用于从操作数栈取走数据、操作数据以及把操作结果重新入栈。在调用方法时,操作数栈也用来准备调用方法的参数以及接收方法返回结果。

  操作数栈的每个位置可以保存一个Java虚拟机定义的任意类型的值,包括long和double。操作数栈有个确定的栈深度,long或double占用两个单位的栈深度,其他数据类型占用一个单位的栈深度。

  操作数栈的数据必须正确地顺序操作,例如,不可以入栈两个int类型的数据,然后当作long类型去操作。有小部分Java虚拟机指令可以不关注操作数的具体数据类型,把所有在运行时数据区中的数据当作裸类型数据来操作,这些指令不可以用来修改数据,也不可以拆散原来不可拆分的数据,这些操作的正确性将会通过class文件的检验过程来强制保障。

  栈帧存在重叠区域,方便方法调用时公用一部分数据,无需进行额外的参数赋值传递。

3 动态链接

  每个栈帧内部包含一个指向当前方法所在类型的运行时常量池的引用,以便对当前方法的代码实现动态链接(在每一次运行期间转化为直接引用)。

4 方法调用

 4.1 正常完成

  方法执行过程中,遇到方法返回的字节码指令时,表示方法正常完成。字节码指令类型取决于方法返回值的数据类型。此时,当前栈帧承担恢复调用者的责任,调用者的代码在被调用方法的返回值压入调用者栈帧的操作数栈后,继续正常执行。

 4.2 异常完成

  方法执行过程中,如果虚拟机内部或遇到athrow字节码指令导致Java虚拟机抛出异常,表示异常完成。

参考资料:《深入理解Java虚拟机(第二版)》《Java虚拟机规范(Java SE 8版)》

转载于:https://www.cnblogs.com/bigshark/p/11219917.html

Java虚拟机知识点【栈帧】相关推荐

  1. java 参数类型不确定_详细解析Java虚拟机的栈帧结构

    什么是栈帧? 正如大家所了解的,Java虚拟机的内存区域被划分为程序计数器.虚拟机栈.本地方法栈.堆和方法区.(什么?你还不知道,赶紧去看看<Java虚拟机内存结构及编码实战>)这次要介绍 ...

  2. Java虚拟机知识点快速复习手册(上)

    前言 本文快速回顾了常考的的知识点,用作面试复习,事半功倍. 上篇主要内容为:虚拟机数据区域,垃圾回收 下篇主要内容为:类加载机制 面试知识点复习手册 全复习手册文章导航 Csdn全复习手册文章导航: ...

  3. Java虚拟机知识点总结

    文章目录 Java虚拟机知识点总结 Java的平台无关性即一次编译处处执行如何实现 为什么JVM不直接将源码解析成机器码去执行 JVM如何加载.class文件/类加载机制 Java虚拟机中哪几种情况会 ...

  4. 虚拟机的分类_「面试必备」Java虚拟机知识点复习手册(下)

    关注我的微信公众号:后端技术漫谈 不定期推送关于后端开发.爬虫.算法题.数据结构方面的原创技术文章,以及生活中的逸闻趣事. 我目前是一名后端开发工程师.主要关注后端开发,数据安全,网络爬虫,物联网,边 ...

  5. java虚拟机基于栈,深入理解java虚拟机(11):基于栈的字节码解释执行引擎

    1.解释执行 编译过程如下 2.基于栈的指令集和基于寄存器的指令集 java编译器输出的指令流,基本是一种基于栈的指令集架构,指令流中的大部分指令都是零地址,依赖于操作数工作.与之相对的是基于寄存器的 ...

  6. 运行时栈帧结构是怎样的?

    写在前面 本文隶属于专栏<100个问题搞定Java虚拟机>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和文献引用请见100个问题搞定Java ...

  7. [java] 虚拟机(JVM)底层结构详解[转]

    [java] 虚拟机(JVM)底层结构详解[转] 本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 在以前的博客里面,我们介绍了在java领 ...

  8. java 虚拟机内存管理_java虚拟机内存管理

    程序计数器: 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器. 程序计数器处于线程独占区 如果线程执行的是Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地 ...

  9. 翻译Java虚拟机的结构

    英文原版:  https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 直接谷歌翻译: Java SE规范 > Java虚拟机 ...

  10. Java程序猿从笨鸟到菜鸟之(九十二)深入java虚拟机(一)——java虚拟机底层结构具体解释...

    本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 在曾经的博客里面,我们介绍了在java领域中大部分的知识点,从最基础的java最基本的语法 ...

最新文章

  1. 对象----《你不知道的JS》
  2. 今天你快乐吗?AI 从走路姿态就能识别你的情绪
  3. 疫情影响全景图:疫情对各行业短中期影响!
  4. STM32 BOOT0连接不当造成死机
  5. Android android-common 常用功能和工具集合
  6. DCF模型里面的括号计算方法
  7. (双指针、二分Binary Search) leetcode 658. Find K closest Elements
  8. 闪屏,default
  9. 第 39 章 ThinkPHP--CURD 操作
  10. 漫步数理统计二十九——函数期望
  11. 怎样才能减少汽车油耗呢?
  12. 基于simulink的有源功率因数校正(APFC) 系统的性能仿真
  13. 基于成本效益的深度信任网络的智能LEACH的多级动态优化附Matlab代码
  14. react + zarm 实现账单列表展示页
  15. IT就业前景怎么样?好不好?
  16. mysql 立方根函数_Java实现牛顿迭代法求解平方根、立方根
  17. linux 应用层gpio中断_树莓派官方自带gpio中断驱动bcm2708_gpio.c原理分析 linux 中断架构 中断子系统...
  18. paperpass论文查重
  19. 手机报彩信易操作平台
  20. 文苑杂志文苑杂志社文苑编辑部2021年第7期目录

热门文章

  1. AC日记——贪婪大陆 洛谷 P2184
  2. 李开复:垂直搜索违背了搜索引擎的发展初衷
  3. C# .net 多线程中集合数据同步
  4. 解决Navicat无法连接到MySQL的问题
  5. Redis随项目启动或CRUD进行缓存数据
  6. AngularJS的ng-click阻止冒泡
  7. node-ffi 调用Golang动态库
  8. MySQL 命令行帮助的使用
  9. Android四大组件之Activity组件
  10. python调用msf_使用python操纵metasploit简单小记