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. JS数组与对象赋值问题

    在W3C的在线编程中经过测试发现以下问题: 当一个数组内部元素为对象时,给数组赋值应该先给对象赋值,然后把该对象push到数组中. 如下所示: 在控制台打印之后的数据格式为下图所示: 如果在给数组赋值 ...

  2. .net core 服务注册生命周期

    在Asp.Net core中的IServiceCollection容器中注册服务的生命周期分以下3种: 1.Transient 通过AddTransient注册,会在IServiceCollectio ...

  3. day28 封装

    目录 一.什么是封装 二.将封装的属性进行隐藏操作 1 如何隐藏: 1.1 强行访问: 1.2 内部逻辑 三.为何要封装 一.什么是封装 封装是面向对象的三大特性中最核心的一个特性 封装<==& ...

  4. 记一次开发CefSharp做浏览器时Shopify绑定不上Paypal问题

    问题:CefSharp做浏览器时Shopify绑定不上Paypal. shopify绑定Paypal的流程大概是如下图所示 步骤1 步骤2 步骤3 步骤4 出现问题大概是在绑定最后一步,并没有如愿的返 ...

  5. msyql事务的四种隔离级别

    一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...

  6. 数据可视化之powerBI基础(十六)PowerQuery的这个小功能,让你轻松发现数据质量问题

    https://zhuanlan.zhihu.com/p/64418072 源数据常常包含各种差错值,为了进行下一步的分析,我们必须先找出并更正这些差错,做这些工作几乎不会有什么快乐感可言,但却往往需 ...

  7. 李航统计学习方法(第二版)(十):决策树CART算法

    1 简介 1.1 介绍 1.2 生成步骤 CART树算法由以下两步组成:(1)决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大;(2)决策树剪枝:用验证数据集对己生成的树进行剪枝并选择最优子 ...

  8. 目录(Django开发)

    python网络编程-socket编程 Django 笔记分享 Django之[基础篇] Django之[进阶篇] Django之 url组件 Django之 Models组件 Django之 adm ...

  9. LeetCode 84 | 单调栈解决最大矩形问题

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第52篇文章,我们一起来看LeetCode第84题,Largest Rectangle in Histogram( ...

  10. WYT的刷子

    WYT的刷子 题目描述 WYT有一把巨大的刷子,刷子的宽度为M米,现在WYT要使用这把大刷子去粉刷有N列的栅栏(每列宽度都为1米:每列的高度单位也为米,由输入数据给出). 使用刷子的规则是: 与地面垂 ...