JDK 8 - JVM 对类的初始化探讨
在《深入理解 Java 虚拟机》(第二版,周志明著)中,作者介绍了 JVM 必须初始化类(或接口)的五种情况,但是是针对 JDK 7 而言的。
那么,在 JDK 8 中,这几种情况有没有变化呢?(我猜测应该会有扩展)
接下来我们探讨一下 JDK 8 中 JVM 类的初始化这一部分内容。
官方文档为 The Java® Virtual Machine Specification, Java SE 8 Edition, 2015-02-13。
类的初始化部分在 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5。
我们先看下《深入理解 Java 虚拟机》(第二版,周志明著)中对类初始化的介绍:
有且只有五种情况下,当发现相关的类没有进行过初始化,虚拟机会触发其初始化:
(1) 调用 new, getstatic, putstatic, invokestatic 这四条指令时,相关类没有初始化;
(2) 使用 java.lang.reflect 包进行反射时,相关类没有初始化;
(3) 初始化子类时,发现父类没有初始化;
(4) 主类(包含 main()方法的类)没有初始化;
(5) JDK 7 中使用动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例正好是对 REF_getStatic, REF_putStatic, REF_invokeStatic 进行方法句柄解析的结果时;
The Java® Virtual Machine Specification, Java SE 8 Edition 中对类或接口进行初始化的内容:
Initialization of a class or interface consists of executing its class or interface initialization method (§2.9).
A class or interface C may be initialized only as a result of:
The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references C (§new, §getstatic, §putstatic, §invokestatic). These instructions reference a class or interface directly or indirectly through either a field reference or a method reference.
Upon execution of a new instruction, the referenced class is initialized if it has not been initialized already.
Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.
The first invocation of a
java.lang.invoke.MethodHandleinstance which was the result of method handle resolution (§5.4.3.5) for a method handle of kind 2 (REF_getStatic), 4 (REF_putStatic), 6 (REF_invokeStatic), or 8 (REF_newInvokeSpecial).This implies that the class of a bootstrap method is initialized when the bootstrap method is invoked for an invokedynamic instruction (§invokedynamic), as part of the continuing resolution of the call site specifier.
Invocation of certain reflective methods in the class library (§2.12), for example, in class
Classor in packagejava.lang.reflect.If C is a class, the initialization of one of its subclasses.
If C is an interface that declares a non-
abstract, non-staticmethod, the initialization of a class that implements C directly or indirectly.If C is a class, its designation as the initial class at Java Virtual Machine startup (§5.2).
从这段可以看到大部分和《深入理解 Java 虚拟机》(第二版,周志明著)中描述的相同,除了两点:
(1) 使用动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例是 REF_newInvokeSpecial 的方法句柄解析结果时,也会触发类的初始化;
(2) 对于接口而言,如果这个接口申明了一个 non-abstract, not-static 方法(实际上就是 JDK 8 新增的 default method),当实现了这个接口的类初始化时也会触发这个接口的初始化。
在初始化前,类/接口必须先经过连接阶段:验证,准备,解析(可选)。
Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.
虚拟机在初始化类/接口时,要注意两个问题:
(1)因为虚拟机是多线程的,要求处理同步问题;
(2)递归初始化的问题。
由虚拟机的具体实现来处理以上两个问题。JDK 8 中使用了一个 procedure 来完成初始化。
当然这个 procedure 需要满足一些条件:比如相关的 Class object 必须完成了验证和准备,并且必须是四种状态中的一种。
详情可以查看文档,有空再探讨。
JDK 8 - JVM 对类的初始化探讨的更多相关文章
- JDK8中JVM对类的初始化探讨
在<深入理解Java虚拟机>(第二版,周志明著)中,作者介绍了JVM必须初始化类(或接口)的五种情况,但是是针对JDK7而言的. 那么,在JDK8中,这几种情况有没有变化呢?(我猜测应该会 ...
- jvm(2)类的初始化(二)和实例化
深入理解Java对象的创建过程:类的初始化与实例化 对象实例化内存分析: 对内存分配情况分析最常见的示例便是对象实例化: Object obj = new Object(); 这段代码的执行会涉及ja ...
- jvm(2)类的初始化(一)
[深入Java虚拟机]之三:类初始化 类初始化是类加载过程的最后一个阶段,到初始化阶段,才真正开始执行类中的Java程序代码. 1,下面说的初始化主要是类变量的初始化,实例变量的初始化触发条件不同(一 ...
- Java技术专区-虚拟机系列-类加载机制(类的初始化)
类加载的生命周期: 加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载 加载 -> 验证 -> 准备 -& ...
- 什么情况下JVM会立即对类进行初始化
虚拟机规范严格规定了有且只有5种情况必须立即对类进行“初始化”(加载.验证.准备等阶段在此之前开始). 遇到new.getstatic.putstatic.invokestatic等4条字节码指令时. ...
- Java虚拟机JVM学习04 类的初始化
Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始 ...
- 关于JVM加载class文件和类的初始化
关于JVM加载class文件和类的初始化 1.JVM加载Class文件的原理机制 1.1.装载 查找并加载类的二进制数据 1.2.链接 验证:确保被加载类的正确性.(安全性考虑) 准备:为类的静态变量 ...
- jvm - 类的初始化过程
我们知道,我们写的java代码称为源码,想要能够被jvm执行首先需要编译成.class文件,那么编译完到使用又都经理的哪些阶段呢?主要分为以下三个阶段: 加载:查找并加载类的二进制数据(.class文 ...
- 实例的初始化由JVM装载类的时候进行,保证了线程的安全性
在23种设计模式中,单例是最简单的设计模式,但是也是很常用的设计模式.从单例的五种实现方式中我们可以看到程序员对性能的不懈追求.下面我将分析单例的五种实现方式的优缺点,并对其在多线程环境下的性能进行测 ...
随机推荐
- .NET自带泛型委托方法Func、Action和Predicate
Func.Action和Predicate是.NET自带的3个泛型委托方法,三个方法的区别其实并不大,要强行给混着用也是可以的,但是我们是有追求的人,把道理讲清楚总是好的. 一.Func是有返回值的方 ...
- windows10添加电源计划修改的快捷方案
转自:http://news.mydrivers.com/1/431/431346.htm 由于目前的Windows 10预览版在UI方面还未优化到位,所以某些设置选项要想找出来是很难的,这时候如果能 ...
- Mysql中in语句排序
这只是Mysql语句的写法,不同数据库写法不太一样, ,,,) order by instr('1,11115,11140,11135',id); 如果不使用order by,in语句查询出来的顺序是 ...
- wpf数据绑定的论述
(1)绑定模式: <Lable x:Name=lab Content={binding UserName} /> <!--binding相当于SetBinding--> Con ...
- Hello Swift
第一个Swift作品,HelloSwift,呵呵.你会把原来的项目用swift改写吗?
- es6语法入门let 和 const 命令
let块级作用域 { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b for循环的计数器,就很合适使用let命令(防 ...
- run as android application过程
1.打包 >> 把所有的class打包成为classes.dex >> AndroidManifest.xml 打包成二进制文件 >> res目录下面的文件打包到r ...
- python--匿名函数lambda
Python语言使用lambda关键字来创建匿名函数. 所谓匿名,即不再使用def语句这样标准的形式定义一个函数. lambda只是一个表达式,而不是一个代码块,函数体比def简单很多. 仅仅能在la ...
- spring学习-3
spring的自动装配 spring IOC容器可以自动装配bean,只需要在bean的autowire属性指定自动装配的模式. 模式: 1.byType:根据类型自动装配.根据bean的类型和当前b ...
- hdu4442 Physical Examination(贪心)
这种样式的最优解问题一看就是贪心.如果一下不好看,那么可以按照由特殊到一般的思维方式,先看n==2时怎么选顺序(这种由特殊到一般的思维方式是思考很多问题的入口): 有两个队时,若先选第一个,则ans= ...
