读《深入理解Java虚拟机》- 笔记05

作者: 阿历Ali | 来源:发表于2018-07-28 20:44 被阅读0次

《深入理解Java虚拟机:JVM高级特性与最佳实践》第2版

第6章 类文件结构

41. 控制转移指令

让JVM有条件或无条件地从指定的位置指令继续执行程序。

分为处理 int 和 reference 类型的条件分支比较,还有检测 null 值的指令。

对于 boolean、byte、char、short 都是使用 int 类型的比较指令完成;对于 long、float、double 类型则会先执行相应类型的比较运算指令,返回一个整型到操作数栈,再执行 int 类型的条件分支比较操作完成整个分支跳转。

42. 同步指令

用 synchronized 实现同步,通过管程 Monitor 来支持。

方法级的同步无需字节码指令控制,执行线程先成功持有管程,然后执行方法,最后方法完成时释放管程。

代码块同步需要 monitorenter 和 moniterexit 指令支持,编译时在字节码插入这两条指令。 monitorenter 和 moniterexit 要成对出现,因此编译器自动生成一个异常处理器,确保处理所有异常,用来执行 monitorexit。

第7章 虚拟机类加载机制

43. 类的生命周期

加载、验证、准备、解析、初始化、使用、卸载。

其中验证、准备、解析统称为连接。

加载、验证、准备、初始化、卸载这5个阶段的顺序是确定的,但不是串行的。换句话说,这5个阶段通常是交叉进行。另外,解析可以在初始化之后再开始,这是为了运行时绑定(动态绑定或晚期绑定)。

44. 类加载时机

Java虚拟机规范并没有强行约束类的加载时机,但是规定了有且只有5种情况必须立即对类初始化(自然加载、验证、准备在此之前开始)。

(1)遇到 new、getstatic、putstatic 或 invokestatic 字节码指令,如果类没有初始化则触发;

(2)使用 java.lang.reflect 包的方法对类进行反射调用,如果类没有初始化则触发;

(3)当初始化一个类的时候,如果发现父类还没有进行初始化,则先触发父类初始化;

注:接口在初始化时,不要求父接口全部完成初始化,只有在使用到父接口的时候才会初始化。

(4)虚拟机启动时要执行的主类;

(5)当使用JDK1.7时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个句柄对应的类没有初始化,则触发初始化。

45. 被动引用不会触发类的初始化

上述5种场景是对一个类的主动引用。被动引用举例:

(1)通过子类引用父类的静态字段,只会触发父类的初始化而不会触发子类的初始化;

(2)定义类的数组时用 newarray 指令触发而不是new;

(3)常量属性在编译阶段存入调用类的常量池种,本质上没有直接引用到定义常量的类,因此不会触发该常量所属类的初始化。


接下来要具体学习类的加载过程了~

待续...

读《深入理解Java虚拟机》- 笔记01

读《深入理解Java虚拟机》- 笔记02

读《深入理解Java虚拟机》- 笔记03

读《深入理解Java虚拟机》- 笔记04

相关文章

网友评论

    本文标题:读《深入理解Java虚拟机》- 笔记05

    本文链接:https://www.haomeiwen.com/subject/oonnmftx.html