classloader
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
- 1
classloader相关推荐
- JVM系列(之ClassLoader)
Class Loader Java运作流程 内部class loader bootstrap class loader --引导类加载器,它负责加载Java的核心类[java.* ](如classpa ...
- Java中的ClassLoader和SPI机制
深入探讨 Java 类加载器 成富是著名的Java专家,在IBM技术网站发表很多Java好文,也有著作. 线程上下文类加载器 线程上下文类加载器(context class loader)是从 JDK ...
- Classloader内存泄露
2019独角兽企业重金招聘Python工程师标准>>> 最近遇到了这个问题,在修改了-Xmx后有时仍然会出现,下文分析的很有启发,看了下文重新分析我的应用,在项目中我使用了sprin ...
- 如何快速写一个违背双亲委托机制的classloader
很多情况下,不得以必须写个classloader来满足需求.例如你一个工程里你想用相同的数据库的多个版本,自己制定了一个jar包目录,没有classloader管理等等.如果是一个遵循java已经规定 ...
- ClassLoader知识收集
阅读提示: 全文认真阅读大约需要1个半小时时间,如果你需要在IDE中验证并理解,大约需要3个小时,如果你想自己写个类似的类加载器并调试,估计还需要3个小时. 该知识点的掌握检测与否,你可以尝试其回答J ...
- Class.forName 和 ClassLoader 到底有啥区别?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 纪莫 来源 | https://www.cnblogs. ...
- 面试题:Class.forName 和 ClassLoader 有什么区别?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:http://t.cn/AiQQ7dwi 在 java 中 ...
- Java基础—ClassLoader的理解
##默认的三个类加载器 Java默认是有三个ClassLoader,按层次关系从上到下依次是:- Bootstrap ClassLoader- Ext ClassLoader- System Clas ...
- java的classloader引用实例_通过实例Java ClassLoader原理
注:本文是个人对java虚拟机规范提到的知识的一点总结. 在Java中,类必须经过jvm使用类装载器(class loader)装载(load)之后才能使用.以主程序(Class A)为例,当jvm调 ...
- 利用classloader同一个项目中加载另一个同名的类_线程上下文类加载器ContextClassLoader内存泄漏隐患...
前提 今天(2020-01-18)在编写Netty相关代码的时候,从Netty源码中的ThreadDeathWatcher和GlobalEventExecutor追溯到两个和线程上下文类加载器Cont ...
最新文章
- wordpress mysql 安装_wordpress 搭建安装教程 1 安装数据库、SQLyog
- VMware网络设置详解 打造超级虚拟网络 (说的最为复杂和全面的)
- Gecko浏览器引擎
- 无人机图像处理工具-亮度、对比度、饱和度调整/匀光匀色/图像去雾
- struts數據庫訪問
- nssl1454-最短路【并查集,贪心】
- 腾讯员工又双叒叕涨工资了,平均月薪已达7.4万
- CSDN《程序员》杂志创始人 蒋涛推荐《程序员求职第一书》
- PHP下SESSION无法跨页传递的解决
- byte[] 转化为 string 转化为汉字和字母
- Arcgis Android - HelloWorld
- 使用CTex排版IEEE论文笔记
- python炫彩界面_炫彩界面库和火花脚本编辑框scintilla制作python IDE框架
- 双系统卸载Linux,重装Deepin
- Skywalking应用
- 学习使用linux下tags文件
- linux cpufreq 设置
- The More You Know: Using Knowledge Graphs for Image Classification 论文总结
- 计算机考研300分什么水平,工科考研300分什么概念
- brocade 300 java版本_博科Brocade 300光纤交换机配置zone教程
热门文章
- HarmonyOS之AI能力·文档检测校正
- 2011年第二届蓝桥杯决赛 —— C语言本科 —— 第一题
- 2016年第七届蓝桥杯 - 省赛 - C/C++大学A组 - F. 寒假作业
- 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1106:年龄与疾病
- 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1044:判断是否为两位数
- Git《二》时光机穿梭
- Exp4 恶意代码分析 20164309
- 【机器视觉】机器视觉博客汇总
- python lambda函数加法_python lambda的使用详解
- c# 接收网络汉字乱码_50种网络故障及解决方法