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. sql语句-如何在SQL以一个表中的数据为条件据查询另一个表中的数据

    select *from 表2where 姓名 in (select 姓名from 表1where 条件) 这个就是用一个表的查询结果当作条件去查询另一个表的数据

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

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

  3. [SpringBoot] 使用yaml文件实现多配置

    SpringBoot 使用yaml文件实现多配置 SpringBoot利用yaml文件实现多配置有两种方式: 单个yml中编写多个配置(Multi-profile YAML Documents) 编写 ...

  4. 如何让元素支持 height:100%效果

    如何让元素支持 height:100%效果? 有两种方法.(1) 设定显式的高度值. 这个没什么好说的,例如,设置 height:600px,或者可以生效的百分比值高度.例如,我们比较常见的:html ...

  5. Python爬虫:手把手教你写迷你爬虫架构

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:我爱学Python 语言&环境 语言:继续用Python开路 ...

  6. mongodb(三):数据库连接(python)

    import pymongo def get_mongodb_conn(**kwargs): db_host = kwargs.get('host') db_port = kwargs.get('po ...

  7. bzoj2295【POJ Challenge】我爱你啊*

    bzoj2295[POJ Challenge]我爱你啊 题意: 求一个字符串中有多少个"luvletter"(不包括引号).字符串长度≤100000. 题解: 连kmp都不用…… ...

  8. js 自定义阻止事件冒泡函数

    // 以下改方法全兼容Chrome function stopBubble(event){ if(event.stopPropagation){   // 兼容火狐(firebox) event.st ...

  9. 解决redis秒杀超卖的问题

    我们再使用redis做秒杀程序的时候,解决超卖问题,是重中之重.以下是一个思路. 用上述思路去做的话,我们再用户点击秒杀的时候,只需要检测,kucun_count中是否能pop出数据,如果能pop出来 ...

  10. Ethical Hacking - NETWORK PENETRATION TESTING(10)

    WPA Craking WPA was designed to address the issues in WEP and provide better encryption. The main is ...