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.MethodHandle
instance 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
Class
or 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-static
method, 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.链接 验证:确保被加载类的正确性.(安全性考虑) 准备:为类的静态变量 ...
随机推荐
- (四):C++分布式框架——状态中心模块
(四):C++分布式框架--状态中心模块 上篇:(三):C++分布式实时应用框架--系统管理模块 技术交流合作QQ群:436466587 欢迎讨论交流 版权声明:本文版权及所用技术归属smartguy ...
- websocket介绍
websocket应用 手动实现的websocket 你所见过的websocket 你一定见过在网站中,有一个游客聊天的聊天框,比如人人影视.这个聊天框是如何实现即时通讯的呢,就是用到了websock ...
- 蓝桥杯 牌型种数 DFS
牌型种数 小明被劫持到X赌城,被迫与其他3人玩牌. 一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张. 这时,小明脑子里突然冒出一个问题: 如果不考虑花色,只考虑点数,也不考虑自己得 ...
- tomcat8权限分离
安装jdk tar xf jdk-8u121-linux-x64.tar.gz mv jdk-* /usr/local/jdk1.8 vi /etc/profile export JAVA_HOME ...
- WebView调用有道词典实如今线查词
WebView(网络视图)能载入显示网页,能够将其视为一个浏览器.它使用了WebKit渲染引擎载入显示网页,用法非常easy,直接在XML文件里写入webview控件就可以,主要代码例如以下: ...
- 为 NativeScript 项目添加 iOS / Android 平台 API 的智能感知
使用 NativeScript ,我们可以很容易的调用平台的原生 API,在开发过程中,我们可以添加这些 API 的 d.ts 文件来提供智能感知,帮助我们更方便的构建媲美原生的 APP. 首先通过 ...
- Java项目中使用Redis缓存案例
缓存的目的是为了提高系统的性能,缓存中的数据主要有两种: 1.热点数据.我们将经常访问到的数据放在缓存中,降低数据库I/O,同时因为缓存的数据的高速查询,加快整个系统的响应速度,也在一定程度上提高并发 ...
- ssm学习(四)--完整的增删改查demo
上一篇文章简要介绍了将sping mvc加入整个框架,算是完成了ssm的集成.本节继续前面的内容,结合spring mvc做一个简单的增删改查demo. 1.首先,重写一下GeckoList.jsp页 ...
- java 单例模式学习笔记
1.单例模式概述 单例模式就是确保类在内存中只有一个对象,该实例必须自动创建,并且对外提供. 2.优缺点 优点:在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模 ...
- Android项目实战(三十九):Android集成Unity3D项目(图文详解)
需求: Unity3D 一般用于做游戏 而且是跨平台的.原本设计是Android 应用端A(原生开发)进行一些业务处理,最后由A 打开Android 应用端B(Unity3D 游戏开发)进行游戏操作. ...