深入分析ClassLoader

why?

ClassLoader,即java类加载器,主要作用是将class加载到JVM内,同时它还要考虑class由谁来加载。在说java的类加载机制之前,还是像前面的博客一样,先说说为什么要知道java的类加载机制。个人认为主要有以下几个原因:

  • 按需加载。JVM启动时不能确定我要加载哪些东西,或者有些类非常大,我只希望用到它时再加载,并非一次性加载所有的class,所以这时候了解了加载机制就可以按需加载了。
  • 类隔离。比如web容器中部署多个应用,应用之间互相可能会有冲突,所以希望尽量隔离,这里可能就要分析各个应用加载的资源和加载顺序之间的冲突,针对这些冲突再自己定些规则,让它们能够愉快地玩耍。
  • 资源回收。如果你不了解java是如何加载资源的,又怎么理解java是如何回收资源的?

what?

一般说到java的类加载机制,都要说到“双亲委派模型”(其实个人很不理解为什么叫“双亲”,其实英文叫“parent”)。使用这种机制,可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。JVM根据 类名+包名+ClassLoader实例ID 来判定两个类是否相同,是否已经加载过(所以这里可以略微扩展下,可以通过创建不同的classloader实例来实现类的热部署)。
有个图很形象(来源见参考资料)。

ClassLoader

注意:如果想形象地看到java的类加载顺序,可以在运行java的时候加个启动参数,即java –verbose

下面结合上图来详细介绍下java的类加载过程。

  • BootStrapClassLoader。它是最顶层的类加载器,是由C++编写而成, 已经内嵌到JVM中了。在JVM启动时会初始化该ClassLoader,它主要用来读取Java的核心类库JRE/lib/rt.jar中所有的class文件,这个jar文件中包含了java规范定义的所有接口及实现。
  • ExtensionClassLoader。它是用来读取Java的一些扩展类库,如读取JRE/lib/ext/*.jar中的包等(这里要注意,有些版本的是没有ext这个目录的)。
  • AppClassLoader。它是用来读取CLASSPATH下指定的所有jar包或目录的类文件,一般情况下这个就是程序中默认的类加载器。
  • CustomClassLoader。它是用户自定义编写的,它用来读取指定类文件 。基于自定义的ClassLoader可用于加载非Classpath中(如从网络上下载的jar或二进制)的jar及目录、还可以在加载前对class文件优一些动作,如解密、编码等。

很多资料和文章里说,ExtClassLoader的父类加载器是BootStrapClassLoader,其实这里省掉了一句话,容易造成很多新手(比如我)的迷惑。严格来说,ExtClassLoader的父类加载器是null,只不过在默认的ClassLoader 的 loadClass 方法中,当parent为null时,是交给BootStrapClassLoader来处理的,而且ExtClassLoader 没有重写默认的loadClass方法,所以,ExtClassLoader也会调用BootStrapLoader类加载器来加载,这就导致“BootStrapClassLoader具备了ExtClassLoader父类加载器的功能”。看一下下面的代码就很容易理解上面这一大段话了。

/**
 * 查看父类加载器
 */
private static void test1() {
    ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
    System.out.println("系统类装载器:" + appClassLoader);
    ClassLoader extensionClassLoader = appClassLoader.getParent();
    System.out.println("系统类装载器的父类加载器——扩展类加载器:" + extensionClassLoader);
    ClassLoader bootstrapClassLoa
  • 35
    点赞
  • 105
    收藏
    觉得还不错? 一键收藏
  • 21
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值