http://baike.baidu.com/view/2174061.htm

什么是类加载器?  与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。

  JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,BootstrapClassLoader是用本地代码实现的,它负责加载核心JavaClass(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由BootstrapClassLoader加载;其中Extension ClassLoader负责加载扩展的Javaclass(例如所有javax.*开头的类和存放在JRE的ext目录下的类),ApplicationClassLoader负责加载应用程序自身的类。

  当运行一个程序的时候,JVM启动,运行bootstrapclassloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。

  注: 学ClassLoader看OSGI

什么时候加载类?

  什么时候JVM会使用ClassLoader加载一个类呢?当你使用java去执行一个类,JVM使用ApplicationClassLoader加载这个类;然后如果类A引用了类B,不管是直接引用还是用Class.forName()引用,JVM就会找到加载类A的ClassLoader,并用这个ClassLoader来加载类B。JVM按照运行时的有效执行语句,来决定是否需要装载新类,从而装载尽可能少的类,这一点和编译类是不相同的。

  Why use your own ClassLoader?

  似乎JVM自身的ClassLoader已经足够了,为什么我们还需要创建自己的ClassLoader呢?

  因为JVM自带的ClassLoader只是懂得从本地文件系统加载标准的java class文件,如果编写你自己的ClassLoader,你可以做到:

  1)在执行非置信代码之前,自动验证数字签名

  2)动态地创建符合用户特定需要的定制化构建类

  3)从特定的场所取得java class,例如数据库中

  4) 等等

  事实上当使用Applet的时候,就用到了特定的ClassLoader,因为这时需要从网络上加载java class,并且要检查相关的安全信息。

  目前的应用服务器大都使用了ClassLoader技术,即使你不需要创建自己的ClassLoader,了解其原理也有助于更好地部署自己的应用。

类加载器的树状结构 & 委托代理模式

  当你决定创建你自己的ClassLoader时,需要继承java.lang.ClassLoader或者它的子类。在实例化每个ClassLoader对象时,需要指定一个父对象;如果没有指定的话,系统自动指定ClassLoader.getSystemClassLoader()为父对象。

  所以当创建自己的Class Loader时,只需要重载findClass()这个方法。

卸载? 重载?

  当一个javaclass被加载到JVM之后,它有没有可能被卸载呢?我们知道Win32有FreeLibrary()函数,Posix有dlclose()函数可以被调用来卸载指定的动态连接库,但是Java并没有提供一个UnloadClass()的方法来卸载指定的类。

  在Java中,java class的卸载仅仅是一种对系统的优化,有助于减少应用对内存的占用。既然是一种优化方法,那么就完全是JVM自行决定如何实现,对Java开发人员来说是完全透明的。

  在什么时候一个java class/interface会被卸载呢?Sun公司的原话是这么说的:"class or interfacemay be unloaded if and only if its class loader is unreachable. Classesloaded by the bootstrap loader may not be unloaded."

  事实上我们关心的不是如何卸载类的,我们关心的是如何更新已经被加载了的类从而更新应用的功能。JSP则是一个非常典型的例子,如果一个JSP文件被更改了,应用服务器则需要把更改后的JSP重新编译,然后加载新生成的类来响应后继的请求。

  其实一个已经加载的类是无法被更新的,如果你试图用同一个ClassLoader再次加载同一个类,就会得到异常(java.lang.LinkageError: duplicate classdefinition),我们只能够重新创建一个新的ClassLoader实例来再次加载新类。至于原来已经加载的类,开发人员不必去管它,因为它可能还有实例正在被使用,只要相关的实例都被内存回收了,那么JVM就会在适当的时候把不会再使用的类卸载。

  使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.

  典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.

  大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。

  当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个, 防止因为不同的类加载器, 导致类型转换异常(ClassCastException).

  参考资料及图片来源——Understanding J2EE Application Server Class Loading Architectures

扩展阅读:
  • 1

    http://www.java2000.net/p8913

  • 2

    http://www.jdon.com/jivejdon/thread/15456.html

  • 3

    http://gceclub.sun.com.cn/yuanchuang/week-9/classloader.html

classloader相关推荐

  1. JVM系列(之ClassLoader)

    Class Loader Java运作流程 内部class loader bootstrap class loader --引导类加载器,它负责加载Java的核心类[java.* ](如classpa ...

  2. Java中的ClassLoader和SPI机制

    深入探讨 Java 类加载器 成富是著名的Java专家,在IBM技术网站发表很多Java好文,也有著作. 线程上下文类加载器 线程上下文类加载器(context class loader)是从 JDK ...

  3. Classloader内存泄露

    2019独角兽企业重金招聘Python工程师标准>>> 最近遇到了这个问题,在修改了-Xmx后有时仍然会出现,下文分析的很有启发,看了下文重新分析我的应用,在项目中我使用了sprin ...

  4. 如何快速写一个违背双亲委托机制的classloader

    很多情况下,不得以必须写个classloader来满足需求.例如你一个工程里你想用相同的数据库的多个版本,自己制定了一个jar包目录,没有classloader管理等等.如果是一个遵循java已经规定 ...

  5. ClassLoader知识收集

    阅读提示: 全文认真阅读大约需要1个半小时时间,如果你需要在IDE中验证并理解,大约需要3个小时,如果你想自己写个类似的类加载器并调试,估计还需要3个小时. 该知识点的掌握检测与否,你可以尝试其回答J ...

  6. Class.forName 和 ClassLoader 到底有啥区别?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 纪莫 来源 | https://www.cnblogs. ...

  7. 面试题:Class.forName 和 ClassLoader 有什么区别?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:http://t.cn/AiQQ7dwi 在 java 中 ...

  8. Java基础—ClassLoader的理解

    ##默认的三个类加载器 Java默认是有三个ClassLoader,按层次关系从上到下依次是:- Bootstrap ClassLoader- Ext ClassLoader- System Clas ...

  9. java的classloader引用实例_通过实例Java ClassLoader原理

    注:本文是个人对java虚拟机规范提到的知识的一点总结. 在Java中,类必须经过jvm使用类装载器(class loader)装载(load)之后才能使用.以主程序(Class A)为例,当jvm调 ...

  10. 利用classloader同一个项目中加载另一个同名的类_线程上下文类加载器ContextClassLoader内存泄漏隐患...

    前提 今天(2020-01-18)在编写Netty相关代码的时候,从Netty源码中的ThreadDeathWatcher和GlobalEventExecutor追溯到两个和线程上下文类加载器Cont ...

最新文章

  1. wordpress mysql 安装_wordpress 搭建安装教程 1 安装数据库、SQLyog
  2. VMware网络设置详解 打造超级虚拟网络 (说的最为复杂和全面的)
  3. Gecko浏览器引擎
  4. 无人机图像处理工具-亮度、对比度、饱和度调整/匀光匀色/图像去雾
  5. struts數據庫訪問
  6. nssl1454-最短路【并查集,贪心】
  7. 腾讯员工又双叒叕涨工资了,平均月薪已达7.4万
  8. CSDN《程序员》杂志创始人 蒋涛推荐《程序员求职第一书》
  9. PHP下SESSION无法跨页传递的解决
  10. byte[] 转化为 string 转化为汉字和字母
  11. Arcgis Android - HelloWorld
  12. 使用CTex排版IEEE论文笔记
  13. python炫彩界面_炫彩界面库和火花脚本编辑框scintilla制作python IDE框架
  14. 双系统卸载Linux,重装Deepin
  15. Skywalking应用
  16. 学习使用linux下tags文件
  17. linux cpufreq 设置
  18. The More You Know: Using Knowledge Graphs for Image Classification 论文总结
  19. 计算机考研300分什么水平,工科考研300分什么概念
  20. brocade 300 java版本_博科Brocade 300光纤交换机配置zone教程

热门文章

  1. HarmonyOS之AI能力·文档检测校正
  2. 2011年第二届蓝桥杯决赛 —— C语言本科 —— 第一题
  3. 2016年第七届蓝桥杯 - 省赛 - C/C++大学A组 - F. 寒假作业
  4. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1106:年龄与疾病
  5. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1044:判断是否为两位数
  6. Git《二》时光机穿梭
  7. Exp4 恶意代码分析 20164309
  8. 【机器视觉】机器视觉博客汇总
  9. python lambda函数加法_python lambda的使用详解
  10. c# 接收网络汉字乱码_50种网络故障及解决方法