在《深入理解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 newgetstaticputstatic, 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 getstaticputstatic, 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 package java.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对类的初始化探讨的更多相关文章

  1. JDK 8 - JVM 对类的初始化探讨

    在<深入理解 Java 虚拟机>(第二版,周志明著)中,作者介绍了 JVM 必须初始化类(或接口)的五种情况,但是是针对 JDK 7 而言的. 那么,在 JDK 8 中,这几种情况有没有变 ...

  2. JDK8中JVM堆内存划分

    一:JVM中内存 JVM中内存通常划分为两个部分,分别为堆内存与栈内存,栈内存主要用运行线程方法 存放本地暂时变量与线程中方法运行时候须要的引用对象地址. JVM全部的对象信息都 存放在堆内存中.相比 ...

  3. jvm(2)类的初始化(二)和实例化

    深入理解Java对象的创建过程:类的初始化与实例化 对象实例化内存分析: 对内存分配情况分析最常见的示例便是对象实例化: Object obj = new Object(); 这段代码的执行会涉及ja ...

  4. jvm(2)类的初始化(一)

    [深入Java虚拟机]之三:类初始化 类初始化是类加载过程的最后一个阶段,到初始化阶段,才真正开始执行类中的Java程序代码. 1,下面说的初始化主要是类变量的初始化,实例变量的初始化触发条件不同(一 ...

  5. Swift中如何化简标准库中冗长的类实例初始化代码

    可能有些童鞋并不知道,在Swift中缩写点符号对于任何类型的任何static成员都有效. 我们实际写一个例子看一下: import UIKit class CFoo{ static let share ...

  6. Java技术专区-虚拟机系列-类加载机制(类的初始化)

      类加载的生命周期:  加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载       加载 -> 验证 -> 准备 -& ...

  7. Java虚拟机JVM学习04 类的初始化

    Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始 ...

  8. jvm中加载类的全过程

    ClassLoader的作用:概括来说就是将编译后的class装载.加载到机器内存中,为了以后的程序的执行提供前提条件. jvm的整个生命周期,如下图所示 加载=>验证=>准备=>解 ...

  9. 关于JVM加载class文件和类的初始化

    关于JVM加载class文件和类的初始化 1.JVM加载Class文件的原理机制 1.1.装载 查找并加载类的二进制数据 1.2.链接 验证:确保被加载类的正确性.(安全性考虑) 准备:为类的静态变量 ...

随机推荐

  1. MySQL之事务的四大特性

    事务就是一组原子性的SQL查询,或者说一个独立的工作单元.如果数据库引擎能够成功地对数据应用该组查询的全部语句,那么久执行该组查询.如果其中任何一条语句因为崩溃或其他原因无法执行,那么所有语句都不会执 ...

  2. Python连接MySQL数据库中各种坑

    第一个坑 要想连接数据库,我们必须拥有MySQL-python这个模块,首先,我在安装这个模块的时候就到了第一个大坑. 常规安装方法:进入cmd 使用 pip install MySQL-python ...

  3. 关于promise的详细讲解

    到处是回调函数,代码非常臃肿难看, Promise 主要用来解决这种编程方式, 将某些代码封装于内部. Promise 直译为"承诺",但一般直接称为 Promise; 代码的可读 ...

  4. python之 json里字典中的value去重

    import simplejson as json with open(r'C:\Users\Desktop\test.txt', 'r' ) as f1, open(r'C:\Users\Deskt ...

  5. nginx防恶意域名解析

    今天无意间查看访问日志发现一个fhxywh.com的域名居然解析到了我的服务器,也就是说通过这个域名也能访问我的博客,这个就是赤裸裸的恶意域名解析了. 这个危害非常大,不仅会影响用户,而且不利于SEO ...

  6. HDU 4193 Non-negative Partial Sums(想法题,单调队列)

    HDU 4193 题意:给n个数字组成的序列(n <= 10^6).求该序列的循环同构序列中,有多少个序列的随意前i项和均大于或等于0. 思路: 这题看到数据规模认为仅仅能用最多O(nlogn) ...

  7. 5个步骤,将 storyboard 从 iphone 版转变为 ipad 版

    1.将 iPhone 版的 Storyboard 复制为 iPad 的,比如 Main_iPad.storyboard 2.用文本编辑器(不要用 Xcode)打开 Main_iPad.storyboa ...

  8. Hadoop之SequenceFile

    Hadoop序列化文件SequenceFile能够用于解决大量小文件(所谓小文件:泛指小于black大小的文件)问题,SequenceFile是Hadoop API提供的一种二进制文件支持.这样的二进 ...

  9. C++11新特性应用--介绍几个新增的便利算法(不更改容器中元素顺序的算法)

    总所周知.C++ STL中有个头文件,名为algorithm.即算法的意思. The header<algorithm>defines a collection of functions ...

  10. Office Add-in 架构和入门

    作者:陈希章 发表于2017年7月12日 前言 从2月26日开始写这个Office 365开发概览系列文章-- https://aka.ms/office365devguide,到现在已经有17篇文章 ...