类从被加载到虚拟机内存中开始,到卸载出内存截止,整个生命周期包括:加载、验证、准备、解析,初始化、使用、卸载七个阶段。其中验证、准备、解析三个部分统称为连接。

类初始化情况:

  • 遇到new、getstatic、putstatic 或 invokestatic 这4条字节码指令时,如果没有初始化,则需要触发初始化。生成这4条指令的最常见Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段,以及调用一个类的静态方法时。

  • 使用java.lang.reflect包的方法对类进行发射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。

  • 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。

  • 当虚拟机启动时,用户需要制定一个要执行的主类,虚拟机会先初始化这个主类。

以上四种场景成为类的主动引用。除此之外所有引用类的方式都不会触发初始化——被动引用。

第一种情况

对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。

package main.java.loadclass;

public class SubClass extends SupperClass{
static {
System.out.println("SubClass init!");
} }
package main.java.loadclass;

public class SupperClass {
static {
System.out.println("supper class");
} public static int value = 123;
}
package main.java.loadclass;

public class NotInitialization {

    public static void main(String[] args){
System.out.println(SubClass.value);
}
}
输出:
supper class
123

第二种情况

package main.java.loadclass;

public class NotInitialization {

    public static void main(String[] args){
SupperClass[] sca = new SupperClass[10];
}
}

运行此段代码无输出值,可见SupperClass未初始化。但是虚拟机会自动生成一个同名的类(继承自Object)进行初始化,创建动作由new array触发。

第三种情况

package main.java.loadclass;

public class ConstClass {

    static {
System.out.println("ConstClass init!");
} public static final String HELLOWORLD = "hello world";
}
package main.java.loadclass; /**
* 常量在编译阶段会存入调用类的常量池中,
* 本质上没有直接引入定义的常量类,
* 因此不会触发定义常量类的初始化。
*/
public class NotInitialization { public static void main(String[] args){ System.out.println(ConstClass.HELLOWORLD);
}
}

加载

加载过程

  • 通过一个类的全限定名来获取定义此类的二进制字节流。

  • 将这个字节流所带变的静态存储结构转化为方法区的运行时数据结构。

  • 在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这个数据的访问入口。

加载访问方式

  • 从本地系统直接加载

  • 通过网络下载class文件

  • 从zip、jar等归档文件中加载class文件

  • 从原有数据库中提取class文件

  • 将java源文件动态编译为class文件

验证

目的

符合JVM加载字节码符合规范

验证过程

  • 文件格式验证

  • 元数据验证:是否符合java语言规范

  • 字节码验证:确保程序语言合法,符合逻辑

  • 符号引用验证:确保下一步的解析能正常执行。

准备

准备阶段的目的是为被加载的静态变量分配内存,并设置默认初始值,如果是final修饰的常量,初始值为设置的值。

解析

  • 解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。

  • 对类的字段和方法进行转换

  • 符号引用:代码在编译阶段,虚拟机并不知道具体引用的地址,所以会用符号引用替代

  • 直接引用:在内存中,将符号引用变成具体的引用地址,可以理解成一个指针,偏移量或者句柄

初始化

什么时候初始化?

  • 当虚拟机启动时,初始化用户指定的主类。

  • 使用new该类实例化对象的时候。

  • 读取或设置静态字段的时候,初始化该静态字段的所在的类

  • 调用类静态方法的时候,初始化该静态方法所在的类

  • 使用反射class.forName("xxx")对类进行反射调用的时候,该类需要初始化。

  • 子类的初始化会触发父类的初始化(1、接口除外,父接口在调用的时候才会初始化,2子类引用父类静态字段,只会引发父类的初始化),

  • 如果一个接口定义了default方法,那么直接实现或间接实现接口的类的初始化,会触发该接口的初始化

  • 当初次调用MethodHandle实例时,初始化该MethodHandle指向的方法所在的类。

初始化顺序

初始化超类 》执行静态初始化 》类变量初始化

  • 父类的静态变量和静态块赋值

  • 自身的静态变量和静态块赋值

  • 父类的成员变量和块赋值

  • 父类构造器赋值:如果父类中含有有残构造器,则在子类构造器中一定要使用“super(参数)”指定调用父类有参的构造器,不然会报错

  • 自身成员变量和块赋值

  • 自身构造赋值

如何追踪类的加载与卸载:

  • 追踪类的加载与卸载过程

-verbose:class
  • 单独追踪类的加载

-XX:+TraceClassLoading
  • 单独追踪类的卸载

-XX:+TraceClassUnloading

JVM虚拟机类加载机制(一)的更多相关文章

  1. 深入理解JVM - 虚拟机类加载机制 - 第七章

    类加载的时机类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括了:加载/验证/准备/解析/初始化/使用/卸载七个阶段.其中验证/准备和解析统称为连接(Linking). 加载.验证.准 ...

  2. 【JVM.6】虚拟机类加载机制

    一.概述 虚拟机类加载机制:虚拟机把描述类的数据从Class文件中加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型. 与那些在编译时需要进行连接工作的语言不同 ...

  3. JVM虚拟机—JVM的类加载机制

    1 什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  4. 深入理解JVM,虚拟机类加载机制

    类加载过程概览 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括以下7个阶段: 加载(Loading) 验证(Verification) 准备(Preparation) 解析(Re ...

  5. 【JVM】虚拟机类加载机制

    什么是类加载 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. <[JVM]类文件结构& ...

  6. JVM学习笔记-第七章-虚拟机类加载机制

    JVM学习笔记-第七章-虚拟机类加载机制 7.1 概述 Java虚拟机描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被 ...

  7. Java虚拟机类加载机制

    看到这个题目,很多人会觉得我写我的java代码,至于类,JVM爱怎么加载就怎么加载,博主有很长一段时间也是这么认为的.随着编程经验的日积月累,越来越感觉到了解虚拟机相关要领的重要性.闲话不多说,老规矩 ...

  8. Java虚拟机类加载机制——案例分析

    转载: Java虚拟机类加载机制--案例分析   在<Java虚拟机类加载机制>一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的最后留了一个悬念给各位,这里来揭开这个悬 ...

  9. Java虚拟机--虚拟机类加载机制

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

随机推荐

  1. 所有整数型包装类对象值的比较,使用equals方法进行比较

    一.整数型包装类对象值的比较,使用equals方法进行比较 题眼:整型包装类.值的比较 注:== :对于基本类型,比较的是值:对于引用类型,比较的是地址值. // 组一Integer i1=new I ...

  2. Windows XP系统搜索故障及处理办法点点通

    故障1:单击资源管理器工具栏上的"搜索"按钮或者按F3,系统无任何响应. 解决方法:首先进入C:\Windows\inf文件夹(该文件夹属性为隐藏),右键单击srchasst.in ...

  3. java线程池之newFixedThreadPool定长线程池

    newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待. 线程池的作用: 线程池作用就是限制系统中执行线程的数量.     根 据系统的环境情况,可以 ...

  4. python 包之 xlwt 操作 excel 教程

    一.安装 pip install xlwt 二.创建表格并写入 创建表格,设置sheet名称 写入指定行列的数据,将表格进行保存 import xlwt # 创建一个workbook并设置编码 wor ...

  5. HMS Core机器学习服务图像超分能力,基于深度学习提升新闻阅读体验

    在移动端阅读资讯时,人们对高分辨率.高质量的图像要求越来越高.但受限于网络流量.存储.图片源等诸多因素,用户无法便捷获得高质量图片.移动端显示设备的高分辨率图片获得问题亟待解决.不久前,HMS Cor ...

  6. 三、MyCat主要配置介绍

    一.配置文件 1.server.xml Mycat的配置文件,设置账号.参数等2.schema.xml Mycat对应的物理数据库和数据库表的配置3.rule.xml Mycat分片(分库分表)规则 ...

  7. Eclipse建立Web项目,手动生成web.xml文件

    相关文章:https://blog.csdn.net/ys_code/article/details/79156188(Web项目建立,手动生成web.xml文件

  8. 学习Keepalived(二)

    一.keepalived简介 keepalived是集群管理中保证集群高可用的一个服务软件,其功能类似于,用来防止单点故障. 二.vrrp协议2.1 vrrp协议简介 在现实的网络环境中,两台需要通信 ...

  9. IOC 初始化源代码阅读之我见

    由于本人的能力有限,只能说出自己的见解,如有错漏什么的,请大家批评指出.由于代码封装太多,这里只列出了我认为的部分最重要的代码,一些简单的封装代码,不在下面列出.由于代码太过于复杂,在本次博客中,只列 ...

  10. 运筹学之"连通图"和"最小枝杈树"和"最短路线问题"

    一.连通图 必须每个点都有关系 图1 不算连通图 图2含有圈v1,v2,v5,可优化 图3就是所需的连通图 注意:图>连通图>树 二.最小枝杈树 获取是所有节点的最小值,只要是连通图就好, ...