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. 结合SpEL使用@Value-基于配置文件或非配置的文件的值注入-Spring Boot

    本文主要介绍Spring @Value 注解注入属性值的使用方法的分析,文章通过示例代码非常详细地介绍,对于每个人的学习或工作都有一定的参考学习价值 在使用spring框架的项目中,@Value是经常 ...

  2. 基于svg的环形进度条

    其实需求是这么一个基于日期的环形进度条,开始用css3写了一下感觉太麻烦了,于是抽了点时间用svg画了一个. 不多说 上代码: css: <style> circle { -webkit- ...

  3. Git管理修改、撤销和删除文件

    目录 备注: 知识点 管理修改 撤销修改 没有git add添加到暂存区时的撤销 git add添加到暂存区后的撤销 git commit提交后的撤销 删除文件 确定从版本库中删除文件 从暂存区把误删 ...

  4. bzoj2160拉拉队排练

    bzoj2160拉拉队排练 题意: 给一个字符串,求最长的k个回文子串(此处回文子串长度必须为奇数)长度的乘积.字符串长度≤1000000 题解: 先用manacher预处理出第i个字符为中心的最长回 ...

  5. JVM垃圾回收(五)

    低延迟垃圾收集器 衡量垃圾收集器的三项最重要的指标是: 内存占用(Footprint).吞吐量(Throughput)和延迟(Latency).三者总体的表现会随技术进步而越来越好,但是要在这三个方面 ...

  6. C++代码规约--命名约定

    目录 通用命名规则 文件命名 类型命名 变量命名 常量命名 函数命名 宏命名 枚举命名 命名空间命名 命名规则的特例 学习自Google C++编程规约 通用命名规则 函数命名, 变量命名, 文件命名 ...

  7. OSCP Learning Notes - Buffer Overflows(3)

    Finding Bad Characters 1. Find the bad charaters in the following website: https://bulbsecurity.com/ ...

  8. OSCP Learning Notes - Post Exploitation(1)

    Linux Post Exploitation Target Sever: Kioptrix Level 1 1. Search the payloads types. msfvenom -l pay ...

  9. Ethical Hacking - GAINING ACCESS(5)

    Server Side Attack Install Metasploit cummunity/pro and active it. Create a new project for the targ ...

  10. STL Stack(栈)学习笔记 + 洛谷 P1449 后缀表达式

    稍微看了看刘汝佳的白皮书,“实用主义”的STL实在是香到我了,而且在实验室大佬的推荐下我开始了stl的学习. 每篇附带一个题目方便理解,那行,直接开始. 毕竟是实用主义,所以就按照给的题目的例子来理解 ...