JVM 何时、如何把 Class 文件加载到内存,形成可以直接使用的 Java 类型,并开始执行代码?

类的生命周期

加载 - 连接(验证、准备、解析)- 初始化 - 使用 - 卸载。

注意,加载、验证、准备、初始化顺序是确定的,但是不是按部就班地「执行」,而是按部就班地「开始」。

另外,为了支持 Java 语言的运行时动态绑定,解析阶段有时候可以在初始化阶段之后再开始。

什么时候进行类加载?

JVM 规范中没有规定什么时候加载类,但是对于初始化时机有严格规定(而加载、验证、准备必须要在初始化之前开始):

触发初始化的条件

  1. 遇到 new、getstatic、putstatic、invokestatic 指令。(final static 字段除外,它是准备阶段被直接赋值)
  2. 反射调用。
  3. 初始化时如果父类没有初始化过,会先进行父类的初始化。(接口除外)(对静态字段,只有直接定义这个字段的类,才会被初始化。看下面代码)
  4. 虚拟机启动时,会优先初始化用户指定的主类。
  5. 初次调用 MethodHandle 实例时,初始化该 MethodHandle 指向的方法所在的类。
  6. 如果一个接口定义了 default 方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化。
public static void main(String[] args) {
System.out.println(B.a);
/*
* 输出:
* A
* 123
*/
} static class A {
static int a = 123; static {
System.out.println("A");
}
} static class B extends A {
static {
System.out.println("B");
}
}

类加载的过程

包括加载、连接(验证、准备、解析)、初始化。

加载 Loading

  1. 通过类的全限定名来获取该类的二进制流
  2. 把二进制流转为方法区的运行时数据结构。
  3. 内存中生成 Class 对象

开发人员也可以通过自定义的类加载器来控制字节流的获取方式(即重写类加载器的 loadClass 方法)。

连接 Linking

验证 Verification

验证字节信息是否符合要求。

准备 Preparation

类变量分配内存,并设置初始值(指基本数据类型的零值)。

如果是 final static 常量,则直接赋值。(JVM 如果发现 Class 文件常量池里,类字段的字段属性表中存在 ConstantValue 属性,会在准备阶段设置为 ConstantValue 属性所指定的值。比如编译期 final static 类常量值会放在 ConstantValue 里。)

解析 Resolution

把常量池里的一些符号引用替换为直接引用(内存地址)。

比如 invokestatic、invokespecial、final 方法,编译期可知,且运行期不可变的方法。

初始化 Initialization

执行类的 <clinit>

<clinit> 方法在编译期根据类变量赋值语句、静态语句块来生成的(顺序跟源代码里定义的顺序相同)。如果源代码没有这些语句,就不会生成该方法。

JVM 会通过加锁保证类的 <clinit> 方法只会执行一次。即在多线程环境中,只能有一个线程去执行,其他线程都需要阻塞等待,直到执行完成。

类加载Class Loading的更多相关文章

  1. 从一道面试题来认识java类加载时机与过程

    说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要的内容. 1  开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可 ...

  2. java类加载时机与过程

    转自:http://www.tuicool.com/articles/QZnENv 说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要 ...

  3. JVM -- 类加载

    学习自周志明老师的<深入理解Java虚拟机>第二版 类的加载时机 如上图所示: 类从被加载到虚拟机内存中开始,直到卸载出内存为止,它的整个生命周期包括了: 加载.验证.准备.解析.初始化. ...

  4. JVM-4.类加载机制

    目录 一.类加载的基础 二.类加载的过程 三.类加载器:分类 四.类加载器:双亲委托模型 五.类加载器:补充 六.初始化时机/主动引用和被动引用[关于实例初始化,参考<Java编程思想05-初始 ...

  5. 从一道面试题来认识java类加载时机与过程【转】

    说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要的内容. 1  开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可 ...

  6. 【java 类加载的深入研究1】loadClass()的研究

    1.开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可是自己把代码运行起来,可是结果并不是自己想象的那样.题目如下: class SingleTon { private static ...

  7. JVM实战---类加载的过程

    任何程序都需要加载到内存才能与CPU进行交流 同理, 字节码.class文件同样需要加载到内存中,才可以实例化类 ClassLoader的使命就是提前加载.class 类文件到内存中 在加载类时,使用 ...

  8. 【转载】java类加载时机与过程

    1  开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可是自己把代码运行起来,可是结果并不是自己想象的那样.题目如下: class SingleTon { private stati ...

  9. JVM-类加载机制

    虚拟机类加载机制  虚拟机把描述的类的数据从class文件加载到内存后,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制.  类加载的时机 类被 ...

随机推荐

  1. 「疫期集训day5」火焰

    我们就像一把穿刺敌人的利刃,把敌人开肠破肚----凡尔登高地前气势汹汹的德军 今天没有考试,挺好,有时间自己做题了 今天主要复习+学习了数据结构,列了个表: 已完成:单调队列,线段树,set/vect ...

  2. Windows 用来定位 DLL 的搜索路径

    参考自:https://msdn.microsoft.com/zh-cn/library/253b8k2c.aspx 通过隐式和显式链接,Windows 首先搜索“已知 DLL”,如 Kernel32 ...

  3. .net Framework4 类库调用Jwt

    通过jwt源码,将其引用的Newtonsoft.Json.dll的9.0版本改为最新的12.0版本后重新生成以下文件. 下载地址: https://files.cnblogs.com/files/Zh ...

  4. 【js】栈方法和队列方法

    栈方法:后进先出,推入(push)和弹出(pop):push("**")返回数组长度,pop()返回弹出的项. var colors = new Array(); // 创建一个数 ...

  5. mysql numeric

    tinyint  1个字节 smallint 2个字节 mediumint 3个字节 int 4个字节 bigint 8个字节

  6. MySQL入门(函数、条件、连接)

    MySQL入门(四) distinct:去重 mysql>: create table t1( id int, x int, y int ); mysql>: insert into t1 ...

  7. 外部应用复制 表格 到word中 设置表格自适应

    word 批量设置表格宽度自适应 描述 : 我们经常从 外部 如 excel,html 等其他文件 中复制的表格到word 文档 经常会出现在 word 中显示不全的问题 主要是源格式的表格 宽度比 ...

  8. JVM 学习笔记(三)

    一:使用jvisualvm工具查看堆内存 visualgc插件下载链接 : https://visualvm.github.io/pluginscenters.html --->选择对应版本链接 ...

  9. DEX文件解析--6、dex文件字段和方法定义解析

    一.前言    前几篇文章链接:       DEX文件解析---1.dex文件头解析       DEX文件解析---2.Dex文件checksum(校验和)解析       DEX文件解析--3. ...

  10. Harbor打怪升级

    目录 一.目标 二.V1.4升级至V1.6 三.V1.6升级至V1.9 四.V1.9升级至V2.0 五.写在最后 一.目标 Harbor V1.4版本升级至V2.0 注: Harbor升级需要注意的是 ...