Java进阶指南:JVM核心知识1.2类加载器

系列文章目录

1:JVM核心知识

        1.1:字节码

        1.2:类加载器



前言

本系列主要针对想进一步进阶Java的开发者,本文介绍Java的类加载器。


一、Java类加载器是什么?

Java类加载器(Java Classloader)是Java运行时环境(Java Runtime Environment)的一部分,负责动态加载Java类到Java虚拟机的内存空间中,用于加载系统、网络或者其他来源的类文件。Java源代码通过javac编译器编译成类文件,然后JVM来执行类文件中的字节码来执行程序。

二、类的生命周期

1. 加载(Loading):找 Class 文件

2. 验证(Verification):验证格式、依赖

3. 准备(Preparation):静态字段、方法表

4. 解析(Resolution):符号解析为引用

5. 初始化(Initialization):构造器、静态变 量赋值、静态代码块

6. 使用(Using)

7. 卸载(Unloading)

三、类加载器三种类型

1. 启动类加载器(BootstrapClassLoader)

启动类加载器主要加载Object,String,JDK安装目录下rt.jar的类。

2. 扩展类加载器(ExtClassLoader)

作为启动类加载器补充,比如JDK,JRE中指定目录下放的jar包。

3. 应用类加载器(AppClassLoader)

负责加载自己编写的,运行时指定classpath中的类。

Q:为什么需要这三种类加载器,按理说只要启动类加载器和应用类加载器不就行了吗?

如果一个JDK要启动很多应用程序,这些应用程序又有共同的依赖,那么把这些共性依赖从应用类加载器提出,放入扩展类加载器中,如果放入启动类加载器,那么对个别应用程序来说就多了一层不必要的包,如果放在应用类加载器,每个应用程序加载都要单独指定一下,很麻烦。

四、类加载器三个特点:

1. 双亲委托

首先我们要知道类加载器的层级

Q:什么是双亲委托?

把自己要加载的类委托给双亲来探测是否加载过,如果加载过,双亲会给子类加载器返回一个引用,如果没有加载过,子类加载器会自己加载。需要注意的是,这个探测要一直往上,也就是说:

如果子类的父亲没有加载过,就会去找子类的爷爷,一直到根加载器。

Q: 为什么需要双亲委托?

如果没有双亲委托,将会加载大量重复的类,造成资源的浪费。

2. 负责依赖

如果加载某个类时,需要加载其他类,那么当前类加载器也会把其他类加载了。

这很好理解,因为我们都遇见过在启动一个Java应用的时候出现找不到类的情况,如果没有负责依赖,我们将寸步难行。

3. 缓存加载

默认情况下所有类都会只加载一次,当类加载完成后,会缓存在内存之中。

Q:学习类加载器有什么作用?

当你发现一些jar包加载不上时可以用debug的方式去找类加载器,查看里面ucp的paths,可以排查当前应用加载的jar包。

这里放一个类加载器实例,仅供参考:

五:怎么指定特定jar包到类加载器中:

1、放到 JDK 的 lib/ext 下,或者 -Djava.ext.dirs

2、 java-cp/classpath 或者 class 文件放到当前路径

3、自定义 ClassLoader 加载

4、拿到当前执行类的 ClassLoader,反射调用 addUrl 方法添加 Jar 或路径(JDK9 无效)


总结

以上就是今天要讲的内容,本文介绍了Java类加载器的内容,这对于排查找不到jar包的问题是非常有用的,接下来我们将介绍JVM的内存模型,敬请期待。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值