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

类加载器三杰


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. Linux CentOS6.6 NFS服务的配置与安装

    一.简介 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客 ...

  2. mybatis框架入门程序:演示通过mybatis实现数据库的查询操作

    我们现在工程基于的数据库见“https://www.cnblogs.com/wyhluckdog/p/10147754.html”这篇博文. 1.mybatis下载 mybatis的代码由githua ...

  3. spring框架之依赖注入(DI)

    1. IOC和DI的概念 * IOC -- Inverse of Control,控制反转,将对象的创建权反转给Spring!! * DI -- Dependency Injection,依赖注入,在 ...

  4. CodeSmith生成SQL Server视图的实体类脚本/对应的生成模板

    C#生成sql视图的实体类 using System;using System.Text;using CodeSmith.Engine;using SchemaExplorer;using Syste ...

  5. python如何查看有哪些模块

    Question: 如何查看正则表达式模块re及其相关函数的意义 1.终端命令行下 python >> import sys >> sys.modules ########## ...

  6. delphi 数据库技术沉浮录--谨给成为历史的BDE

    2014年9月,delphi xe7 出来了,这次在数据库技术方面,彻底抛掉了从1995 年 delphi 1.0 就自带的(Borland Database Engine)数据库访问技术.从而宣告了 ...

  7. ajax序列化表单,再也不用通过data去一个个的传值了

    jQuery的serialize()方法通过序列化表单值,创建URL编码文本字符串,我们就可以选择一个或多个表单元素,也可以直接选择form将其序列化 这样,我们就可以把序列化的值传给ajax()作为 ...

  8. 【Unity】2.4 层次视图(Hierarchy)

    分类:Unity.C#.VS2015 创建日期:2016-03-29 一.简介 层级视图 (Hierarchy) 包含当前场景中的每个游戏对象 (GameObject).有些是三维模型等资源文件的直接 ...

  9. Python 学习目录

    第一章 Python基础 第二章 Python基础 第三章 Python基础-文件操作&函数 1.python文件处理 2.py-函数基础 3.py-函数进阶 第四章 Python基础-常用模 ...

  10. sql笔试练习

    转:http://www.360doc.com/content/16/0919/17/14804661_592046675.shtml 本文是在Cat Qi的参考原帖的基础之上经本人一题一题练习后编辑 ...