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种设计模式中,单例是最简单的设计模式,但是也是很常用的设计模式.从单例的五种实现方式中我们可以看到程序员对性能的不懈追求.下面我将分析单例的五种实现方式的优缺点,并对其在多线程环境下的性能进行测 ...
随机推荐
- Mssql 比较好的写法
DECLARE @date DATETIME= '2016-11-01'; DECLARE @date2 DATETIME= DATEADD(day, 1, @date); Declare @1 Ta ...
- 查找和删除倒数第n个节点的问题
class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public class NthNodeFromEnd ...
- Vue v-if条件渲染
1.简单的v-if指令,代码如下 <!DOCTYPE html> <html> <head lang="en"> <meta charse ...
- UOJ132 【NOI2015】小园丁与老司机
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 从性能的角度谈SQL Server聚集索引键的选择
简介 在SQL Server中,数据是按页进行存放的.而为表加上聚集索引后,SQL Server对于数据的查找就是按照聚集索引的列作为关键字进行了.因此对于聚集索引的选择对性能的影响就变得十分重要 ...
- java:file文件类
public class FileDemo { public static File file; public static void main(String args[]) { String s = ...
- MySQL 分区知识点(二)
前言: MySQL 5.1+ 版本就开始支持分区功能了. 分区本质上就是在物理文件层面划分了多个物理子表来支撑,或者说是一组底层表的句柄对象的封装. 对于分区表的请求,都是通过句柄对象转化成对存储引擎 ...
- 在ubuntu上安装svn+apache2
参考网站: http://www.thinksaas.cn/group/topic/335434/ http://blog.sina.com.cn/s/blog_3eba8f1c0100dqk1.ht ...
- fasttext和cnn的比较,使用keras imdb看效果——cnn要慢10倍。
fasttext: '''This example demonstrates the use of fasttext for text classification Based on Joulin e ...
- python 实现一个TwoSum的例子
今天无意中看到一个题目,也不是很难,就想着用python实现以下: 题目是数组中的两个数相加等于输入的一个target,然后输出数组的下标. 比如: [1,2,3,4,5,6] target=7 返 ...
