Java类加载机制浅析

 

目录

1、装载(Load)

2、链接(Link)

 2.1、验证(Verify)

 2.2、准备(Prepare)

 2.3、解析(Resolve)

3、初始化(Initialize)

4、类加载器ClassLoader

 4.1类加载器分类 

5、双亲委派机制 

  5.1、检查某个类是否已经加载 

  5.2、加载顺序

 5.3、打破双亲委派机制


所谓类加载机制就是

虚拟机把Class文件加载到内存
并对数据进行校验,转换解析和初始化
形成可以虚拟机直接使用的Java类型,即java.lang.Class

 

 

1、装载(Load)

  查找和导入class文件

(1)通过一个类的全限定名获取定义此类的二进制字节流

(2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

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

Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。在
Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口

 方法区:类信息、常量、静态变量、即时编译器编译后的代码

堆:代表某个类的java.lang.Class对象

2、链接(Link)

 2.1、验证(Verify)

   验证的目的主要是保证被加载类的正确性

  •      文件格式验证
  •      元数据验证
  •      字节码验证
  •      符号引用验证

 2.2、准备(Prepare)

     为类的静态变量分配内存,并将其初始化为默认值

public class Demo1 {
  private static int i;
  public static void main(String[] args) {
    // 正常打印出0,因为静态变量i在准备阶段会有默认值0
    System.out.println(i);
 }
}

public class Demo2 {
  public static void main(String[] args) {
    // 编译通不过,因为局部变量没有赋值不能被使用
    int i;
    System.out.println(i);
 }
}

 2.3、解析(Resolve)

把类中的符号引用转换为直接引用(物理内存引用)

   符号引用就是一组符号来描述目标,可以是任何字面量。

   直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。
解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进
行。

3、初始化(Initialize)

对类的静态变量,静态代码块执行初始化操作

4、类加载器ClassLoader

在装载(Load)阶段,其中第(1)步:通过类的全限定名获取其定义的二进制字节流,需要借助类装载
器完成,顾名思义,就是用来装载Class文件的。

 4.1类加载器分类 

  •   Bootstrap ClassLoader 负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class或Xbootclassoath选项指定的jar包。由c++实现,不是ClassLoader子类。
  •   Extension ClassLoader 负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包。
  •   App ClassLoader 负责加载classpath中指定的jar包及Djava.class.path所指定目录下的类和jar包。
  •   Custom ClassLoader 通过java.lang.ClassLoader的子类自定义加载class,属于应用程序根据自身需要自定义的ClassLoader,如Tomcat、Jboss都会根据j2ee规范自行实现ClassLoader。

/**
 * @ClassName JvmTest
 * @Description: TODO
 * @Author 马志涛
 * @Date 2020/3/31
 * @Version V1.0
 **/
public class JvmTest {
    public static void main(String[] args) {
        // App ClassLoader
        System.out.println(new JvmTest().getClass().getClassLoader());
        // Ext ClassLoader
        System.out.println(new JvmTest().getClass().getClassLoader().getParent());
        // Bootstrap ClassLoader
        System.out.println(new JvmTest().getClass().getClassLoader().getParent().getParent());
        System.out.println(new String().getClass().getClassLoader());
    }
} 

输出结果

sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@4c873330
null
null 

5、双亲委派机制 

  5.1、检查某个类是否已经加载 

    自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个ClassLoader已加载,就视为已加载此类,保证此类只被ClassLoader加载一次。

  5.2、加载顺序

   自顶向下,也就是由上层来逐层尝试加载此类。

 5.3、打破双亲委派机制

   1、Tomcat中的类加载机制

   

2、SPI机制 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值