JDK8中JVM对类的初始化探讨
在《深入理解Java虚拟机》(第二版,周志明著)中,作者介绍了JVM必须初始化类(或接口)的五种情况,但是是针对JDK7而言的。
那么,在JDK8中,这几种情况有没有变化呢?(我猜测应该会有扩展)
接下来我们探讨一下JDK8中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) 主类(包含maini()方法的类)没有初始化;
(5) JDK7中使用动态语言支持时,如果一个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方法,当实现了这个接口的类初始化时也会触发这个接口的初始化。
在初始化前,类/接口必须先经过连接阶段:验证,准备,解析(可选)。
Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.
虚拟机在初始化类/接口时,要注意两个问题:
(1)因为虚拟机是多线程的,要求处理同步问题;
(2)递归初始化的问题。
由虚拟机的具体实现来负责处理以上两个问题。JDK8中使用了一个procedure来完成初始化。
当然这个procedure需要一些条件的满足,比如相关的Class object必须已经完成了验证和准备,并且必须是四种状态中的一种。
详情可以查看文档,有空再探讨。
JDK8中JVM对类的初始化探讨的更多相关文章
- JDK 8 - JVM 对类的初始化探讨
在<深入理解 Java 虚拟机>(第二版,周志明著)中,作者介绍了 JVM 必须初始化类(或接口)的五种情况,但是是针对 JDK 7 而言的. 那么,在 JDK 8 中,这几种情况有没有变 ...
- JDK8中JVM堆内存划分
一:JVM中内存 JVM中内存通常划分为两个部分,分别为堆内存与栈内存,栈内存主要用运行线程方法 存放本地暂时变量与线程中方法运行时候须要的引用对象地址. JVM全部的对象信息都 存放在堆内存中.相比 ...
- jvm(2)类的初始化(二)和实例化
深入理解Java对象的创建过程:类的初始化与实例化 对象实例化内存分析: 对内存分配情况分析最常见的示例便是对象实例化: Object obj = new Object(); 这段代码的执行会涉及ja ...
- jvm(2)类的初始化(一)
[深入Java虚拟机]之三:类初始化 类初始化是类加载过程的最后一个阶段,到初始化阶段,才真正开始执行类中的Java程序代码. 1,下面说的初始化主要是类变量的初始化,实例变量的初始化触发条件不同(一 ...
- Swift中如何化简标准库中冗长的类实例初始化代码
可能有些童鞋并不知道,在Swift中缩写点符号对于任何类型的任何static成员都有效. 我们实际写一个例子看一下: import UIKit class CFoo{ static let share ...
- Java技术专区-虚拟机系列-类加载机制(类的初始化)
类加载的生命周期: 加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载 加载 -> 验证 -> 准备 -& ...
- Java虚拟机JVM学习04 类的初始化
Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始 ...
- jvm中加载类的全过程
ClassLoader的作用:概括来说就是将编译后的class装载.加载到机器内存中,为了以后的程序的执行提供前提条件. jvm的整个生命周期,如下图所示 加载=>验证=>准备=>解 ...
- 关于JVM加载class文件和类的初始化
关于JVM加载class文件和类的初始化 1.JVM加载Class文件的原理机制 1.1.装载 查找并加载类的二进制数据 1.2.链接 验证:确保被加载类的正确性.(安全性考虑) 准备:为类的静态变量 ...
随机推荐
- Python入门 - 时间处理
本讲主要介绍python时间处理方式,比如获取当前的时间: import time ftime = time.strftime("%Y年%m月%d日%H点%M分%S秒", time ...
- HDU5804--Price List
Price List Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others) Tot ...
- 匈牙利标记法定义ECMAScript变量前缀
匈牙利标记法定义ECMAScript变量前缀 类型 前缀 示例 数组 a aArray 布尔型 b bMale 浮点型(数字) f fTax 函数 fn fnSwap 整型(数字) i iAge ...
- 洛谷 P3928 Sequence
题目描述 小强喜欢数列.有一天,他心血来潮,写下了三个长度均为n的数列. 阿米巴也很喜欢数列.但是他只喜欢其中一种,波动数列. 阿米巴把他的喜好告诉了小强.小强便打算找出这三个数列内的最长波动数列. ...
- require.js模块化写法
模块化 模块就是实现特定功能的一组方法.只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块. 下述两种写法等价 exports 对象是当前模块的导出对象,用于导出模块公有方法和属性. ...
- Jarvis OJ - [XMAN]level0 - Writeup
差不多最简单的pwn了吧,不过本菜鸟还是要发出来镇楼 分析一下,checksec 查看程序的各种保护机制 没有金丝雀,没有pie 执行时输出Hello,World,在进行输入,溢出嘛 开工 丢到id ...
- Django使用遇到的各种问题及解决方法
从Django的 搭建开始,遇到的问题就不断,网站还没有发布,就出错了,我查了好多资料,啃得了不少东西,也没有找到合适的方法,终于没办法了,自己硬着头皮往下读,终于解决了这些问题,下面分享给大家. 代 ...
- lua 中pairs 和 ipairs差别
ipairs 和pairs在lua中都是遍历tbale的函数可是两者有差别 1.pairs遍历table中的全部的key-vale 而ipairs会依据key的数值从1開始加1递增遍历相应的table ...
- Javascript--cookie创建与查看
创建cookie 以下代码将创建一个cookie,该cookie名称为UserName,值为Paul,过期时间为7天后(2015年6月29日) <span style="font-si ...
- Python 爬虫 爬校花网!!
爬虫:是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本 1.福利来了 校花网 ,首先说为什么要爬这个网站呢,第一这个网站简单爬起来容易不会受到打击,第二呢 你懂得... 1.第一步,需要下载 ...
