【JDK源码级别剖析JVM类加载机制】

一、Java中类加载过程

1.1、类运行过程

我们在启动一个类的过程中,首先是由java.exe调用jvm.dll创建Java虚拟机,再由其虚拟机创建一个引导类加载器实例,获取到对应的类加载器后,加载执行的类资源后调用其main执行的入口方法,执行相关的业务逻辑代码后,Java程序运行结束,JVM就销毁,相关的图示如下:
在这里插入图片描述

1.2、类加载过程

加载器类的过程主要分为以下步骤:

  1. 加载:也就是从磁盘上读取类的class文件
  2. 验证:这一步主要是验证读取的class文件的格式是否是正确的;
  3. 准备:将定义好的静态变量设置默认值,分配内存
  4. 解析:这里会将符号引用转变为直接引用,直接引用中分为静态连接和动态连接。详见名词解释;
  5. 初始化:对静态变量进行赋值,以及执行静态代码块

具体过程如下图示:
在这里插入图片描述
类加载到JVM的方法区中,主要包含:运行时常量池、类型信息、字段信息、方法信息、类加载的引用(当前这个类到类加载实例的引用)、对应的class实例引用

二、Java的类加载器和双亲委派模型

2.1、类加载器的分类

java中的类加载器主要分为四类,他们分别是:引导类加载器、扩展类加载器、应用类加载器、自定义加载器,各自的加载器资源下图示:
在这里插入图片描述

2.2、类加载器的初始化过程

  1. 首先创建的JVM启动器实例sun.misc.Launcher,在这个Launcher构造方法内部,创建了两个类加载器,分别为:sun.misc.Launcher.ExtClassLoader和sun.misc.Launcher.AppClassLoad,并且JVM默认使用Launcher的getClassLoader()方法返回的类加载器为:AppClassLoader实例,可详见底层Launcher类,如下图示:
    在这里插入图片描述
    在这里插入图片描述

2.3、双亲委派机制

1、我们可以先看一个类加载到JVM的过程,所使用到类加载器的过程是一个什么样的

首先,接2.2小结所说,JVM默认使用Launcher的getClassLoader()方法返回的类加载器为:AppClassLoader实例,AppClassLoader的loadClass方法最终会调用其父类ClassLoader的loadClass方法,该方法的大体逻辑如下:

  • 首先,会检查指定的类是否已经加载过了,如果加载过了,就不需要再加载了,直接返回,底层的逻辑代码如下:
    在这里插入图片描述

  • 如果这个类没有被加载过,就先判断其是否有父加载类,如果有,就调父加载类进行加载,如果没有,就调用bootstrap加载类加载,图示如下:
    在这里插入图片描述

  • 如果父加载器及bootstrap类加载器都没有找到指定的类,那么调用当前类加载器的findClass方法来完成类加载,底层代码如下图示:
    在这里插入图片描述
    那我们再回到最初的问题,加载一个类的过程,首先是会先判断其在已加载的列表中是否存在,存在就返回,不存在就先判断是否有父加载类,有的话,就让父加载类加载,如果父加载类以及bootstrap都没加载出,那才使用当前类加载器加载,这样一个过程,我们就称之为类加载的双亲委派机制

2、那为什么要设置这种双亲委派的类加载机制呢
其实主要有两个方面,分别为:

  • 沙箱安全机制:主要是能够保护java核心类库资源不会被其他新写的同包同名的类给覆盖掉,这样子可以防止核心的API库被篡改
  • 类不被重复加载:当父类已经加载过该类了,那就没有必要让子加载类再重新加载一遍,这可以保证加载类的唯一性

三、自定义类加载器与打破双亲委派机制

3.1、自定义类加载器示例

自定义的类我们需要继承至ClassLoader,从写其loaderClass(定义其类加载的逻辑==>可打破双亲委派模型)和findClass方法,具体如下:
在这里插入图片描述

在这里插入图片描述

3.2、自定义类加载器示例运行结果

其运行结果1如下(没有从写loadClass方法):
在这里插入图片描述
其运行结果2如下(从写loadClass方法):
在这里插入图片描述

四、总结

4.1、首先我们先知道java类运行和加载的过程是如何运行的

运行时,由java.exe调用jvm.dll创建一个java虚拟机,java虚拟机同时创建了一个sun.misc.Launcher实例,这个实例的构造方法中会同时创建两个类加载器,分别是ExtClassLoader和AppClassLoader,接下来就是去加载类(双亲委派机制),读取类的过程:加载=>验证=>准备=>解析=>初始化;

4.2、类的双亲委派机制(原因以及底层源码机制)

在这里插入图片描述

4.3、自定义类加载器及打破双亲委派

自定义的类我们需要继承至ClassLoader,从写其loaderClass(定义其类加载的逻辑==>可打破双亲委派模型)和findClass方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值