本文由作者张远道授权网易云社区发布。

类加载器三杰


jvm有三类classloader,分别是bootstrap classloader,extended classloader以及system classloader。

bootstrap classloader是系统在启动jvm时默认加载的。当用户在命令行输入java Test时,系统会首先加载jvm。在windows系统下,jvm的路径通常位于%JAVA_HOME%/jdk/jre/client/jvm.dll和%JAVA_HOME%/jdk/jre/server/jvm.dll.

bootstrap classloader加载后,会载入extended classloader,并将extended classloader的父类设为bootstrap classloader。然后,bootstrap classloader接着载入system classloader,并将system classloader的父类设为extended classloader。至此,bootstrap--extended--system三级继承结构形成。

bootstrap classloader在jvm启动之后自动加载。bootstrap  classloader由c实现,不属于java类。

extended classloader由java实现,通常为sun.misc.Lancher$ExtClassLoader.

system classloader由java实现,通常为sun.misc.Lancher$AppClassLoader.

其中,

  • bootstrap classloader负责加载sun.boot.class.path路径下的.class文件以及jar包。

  • extended classloader负责加载java.ext.dirs路径下的.class文件以及jar包。

  • system classloader负责加载java.class.path路径下的.class文件以及jar包。

sun.boot.class.path通常对应环境变量CLASSPATH的路径。

java.ext.dirs通常对应JAVA_HOME/jre/lib/ext目录。

java.class.path对应用户自身的类路径。

类加载到何处


据可靠情报,jvm由方法区,堆,栈,pc寄存器和本地方法栈构成。类加载器的任务就是将class二进制文件加载到方法区,供虚拟机模制出在堆中存放的对象。


双亲委托机制


classloader加载类的过程为:

  1. 检查被加载类是否被加载。

  2. 如果没有被加载则调用父classloader加载该类。

  3. 如果1、2不成功,则仍由自身进行类加载。

这种机制又叫双亲委派机制。

双亲委派机制的好处是,避免多个类加载器加载同一个类的不同拷贝到内存(jvm的方法区)中。因为如果类A由ClassLoaderA加载,同时,又被ClassLoaderB加载,这样,内存中就会存在两份不同的A的定义,于是形成A既是ClassLoaderA罩的,又是ClassLoaderB罩着,造成灾难性后果。

用户自定义类的加载顺序通常为:

首先调用AppClassLoader加载类,AppClassLoader调用ExtClassLoader,ExtClassLoader调用BootClassLoader,BootClassLoader在sun.boot.class.path寻找改类,没找到,加载失败;ExtClassLoader也未加载类,失败,最后由AppClassLoader加载成功。从这个加载顺序可以看出来,三个类加载器的对类的可见性是不同的。

java中的类是由java的全名以及类的classloader来限定的。只有当二者完全一样才会认为是同一个类。否则是不同的类。因此,可以定义一个同名的类,包名也一样,只要保证该类被不同的类加载器加载即可。


当前类加载器和线程上下文类加载器


当前类加载器

当前类加载器是指当前方法所在的类使用的类加载器。在程序中使用Class.forName或者Class.getResource抑或Class.class时就是使用的该类加载器。

线程上下文类加载器

线程上下文类加载器可以不遵循双亲委派机制。线程的上下文类加载器有Thread.currentThread().setContextClassLoader()来为当前线程设置线程上下文类加载器。如果没有设置当前线程的上下文类加载器,则继承父类的上下文类加载器。

为什么还需要线程上下文类加载器?

考虑一种情况,当我们的程序必须由jvm的核心代码去加载第三方类的时候。比如jndi,jndi的核心是rt.jar包中实现的,由Bootstrap classloader负责加载,但是jndi必须加载第三方厂商的具体的jndi实现,这个时候调用Bootstrap加载只对其子类加载器可见的类,就会出现失败。这个时候就可以使用线程上下文类加载器。

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请访问网易云社区

相关文章:
【推荐】 MongoDB的正确使用姿势
【推荐】 扫脸动画
【推荐】 AndroidTV开发(4)

浅谈java classloader的更多相关文章

  1. 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance

    浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...

  2. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  3. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  4. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  5. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  6. 浅谈JAVA集合框架

    浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...

  7. 浅谈java性能分析

    浅谈java性能分析,效能分析 在老师强烈的要求下做了效能分析,对上次写过的词频统计的程序进行分析以及改进. 对于效能分析:我个人很浅显的认为就是程序的运行效率,代码的执行效率等等. java做性能测 ...

  8. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  9. !! 浅谈Java学习方法和后期面试技巧

    浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要 ...

随机推荐

  1. win10下zip安装mysql5.7的一些问题

    一.MySQL下载地址: http://dev.mysql.com/downloads/mysql/ 我们下载zip版本的   二.解压zip文件   三.复制一份里面的my-default.ini为 ...

  2. mvc EF 从数据库更新实体,添加视图实体时添加不上的问题

    视图对象没有一列为非null的,解决办法,在视图中,将某一列排除为null的可能,比如:isnull(te,1),即可.

  3. Nginx 分析access日志文件

    Nginx Access Log日志统计分析常用命令 IP相关统计 统计IP访问量 awk '{print $1}' access.log | sort -n | uniq | wc -l 查看某一时 ...

  4. mysql contact_ws函数 字符串被截断问题

    contact函数默认有字符串长度限制,解决方法:SET group_concat_max_len = 20000这个参数设置一下就好了

  5. svn回退版本/取消修改

    取消对代码的修改分为两种情况:   第一种情况:改动没有被提交(commit). 这种情况下,使用svn revert就能取消之前的修改. svn revert用法如下: # svn revert [ ...

  6. NOIP 2016 游记

  7. git 记住用户名和密码

    git 记住用户名和密码 在使用 git 时,如果用的是 HTTPS 的方式,则每次提交,都会让输入用户名和密码,久而久之,就会感觉非常麻烦,那么该如何解决呢? 1. 使用 SSH,添加 ssh ke ...

  8. jquery validate 之多tab页同时校验问题

    1.设置多tab页同时校验: $("form").validate({ignore: ":hidden", ignore: ""}); 由于 ...

  9. XE4 for ios 谨慎处理字符串

    由于xe4 for ios  里面的字符串处理有变化,具体可以参考官方文档,这两天帮一个朋友调试ios 的 应用,由于没有注意这一块,折腾了很长时间.特此记录下来,希望其他人不要走弯路. 以下面代码为 ...

  10. 【Unity】2.0 第2章 Unity编辑器和基本操作

    分类:Unity.C#.VS2015 创建日期:2016-03-26 本章要点: 1.掌握Unity 5.3.4编辑器视图和菜单项及其含义,这是入门的最基础部分,必须掌握. 2.了解最基本的操作,先学 ...