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

类加载器三杰


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. Spring依赖注入servlet会话监听器

    Spring提供了一个 “ContextLoaderListener” 监听器,以使 Spring 依赖注入到会话监听器. 在本教程中,通过添加一个 Spring 依赖注入一个bean 到会话监听器修 ...

  2. PAT 1062 最简分数(20)(代码+思路)

    1062 最简分数(20 分) 一个分数一般写成两个整数相除的形式:N/M,其中 M 不为0.最简分数是指分子和分母没有公约数的分数表示形式. 现给定两个不相等的正分数 N​1​​/M​1​​ 和 N ...

  3. phpstrom+xdebug配置

    1.确认是否安装了xdebug 2.在php.ini文件中配置如下 [xdebug] zend_extension="D:\wamp\php-5.6.2-x64\ext\php_xdebug ...

  4. Mina 系列(二)之基础

    Mina 系列(二)之基础 Mina 使用起来多么简洁方便呀,就是不具备 Java NIO 的基础,只要了解 Mina 常用的 API,就可以灵活使用并完成应用开发. 1. Mina 概述 首先,看 ...

  5. dwr 框架 ,实现 ajax 的java 框架

    1. 引入 dwr.jar 包 2. 配置web.xml 文件 ,拦截请求 <servlet> <servlet-name>dwr-invoker</servlet-na ...

  6. mysql 导入导出摘要

    1.导入by数据文件. mysql>load data infile '文件路径' into table 表名 fields terminated by '字段分隔符' lines termin ...

  7. 让IIS 7 如同IIS 8 第一次请求不变慢

    当我们把网站部署在IIS7或IIS6S的时候,每当IIS或是Application Pool重启后,第一次请求网站反应总是很慢,原因大家都知道(不知道可以参考这个动画说明ASP.NET网页第一个Req ...

  8. Selenium安装中的一些问题及解决办法-软硕1703班3组整理分享

    非常感谢软件工程硕士1703班3组同学的热心,他们将安装Selenium过程中踩过的坑替大家填上了.希望还没有来得及踩坑的,或者掉进坑里还没爬出来的小组,能顺利跨过去这个安装的坑. 如下是原文. Se ...

  9. sql server 2008安装的时候选NT AUTHORITY\NEWORK SERVICE 还是选 NT AUTHORITY\SYSTEM ?

    sql server 2008安装的时候选NT AUTHORITY\NEWORK SERVICE 还是选 NT AUTHORITY\SYSTEM ? sql server 2008安装的时候选NT A ...

  10. Linux服务器部署系列之六—远程管理篇

    做为网络管理员,我们不可能总是在机房操作服务器,对于windows服务器,我们可以通过远程终端或netmeeting进行操作.但是对于Linux服务器呢?我们也可以使用远程工具进行操作,常用的远程管理 ...