JVM自带的三个加载器
- 根类加载器:BootstrapClassLoader
由C++编写,没有父加载器,加载JVM核心类库(jdk/jre/lib目录下),没有继承java.lang.ClassLoader
- 扩展类加载器:ExtensionClassLoader
由Java实现,父加载器为Bootstrap,加载扩展类库(jdk/jre/lib/ext目录下),继承java.lang.ClassLoader
- 系统类(应用类)加载器:AppClassLoader
由Java实现,父加载器为Extension,加载环境变量classpath或系统属性java.class.path目录中加载类库,继承java.lang.ClassLoader,它是用户自定义类加载器的默认父加载器
- 用户自定义类加载器:User defined Class Loader
必须继承java.lang.ClassLoader
注:父子类加载器并非是继承关系,也就是说子加载器不一定继承了父加载器
双亲委派模型
- 双亲委派模型:类加载器之间的委托机制,就是双亲委派模型
- 双亲委派模型工作过程:当一个类加载器,接收到类加载请求之后,会先委托给父加载器,每一层加载器都是如此,最终先由BootstrapClassLoader加载,如果父加载器加载不了,再由子加载器加载,当所有加载器加载不了,就会报出ClassNotFound
- 父委托机制的优点:提高了系统的安全性,如果不是父委托机制,那么就是我自己定义的恶意类可以让我自己的类加载器加载,从而造成系统的风险
类的卸载
JVM自带加载器加载的类始终不会被卸载,用户自定义加载器加载的类会被卸载
类加载过程
- 类的加载:是将类的.class文件中的二进制数据,读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构
- 加载.Class文件的方式:
1> 从本地系统中直接加载
2> 通过网络下载加载
3> 从zip,jar等加载
4> 从专有数据库中加载
5> 将Java源文件动态编译为.class文件
Java程序对类的使用
- Java程序对类的使用方式可分为两种
主动使用、被动使用
- 所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始 化他们
- 主动使用(六种)
1> 创建类的实例
2> 访问某个类或接口的静态变量,或者对该静态 变量赋值
3> 调用类的静态方法
4> 反射(如 Class.forName(“com.shengsiyuan.Test”) )
5> 初始化一个类的子类
6> Java虚拟机启动时被标明为启动类的类(Java Test)
除了以上六种情况,其他使用Java类的方 式都被看作是对类的被动使用,都不会导
致类的初始化
TomcatClassLoader的委托机制
- TomcatClassLoader执行流程:Tomcat违反了双亲委派模型;当接收到类加载请求后,没有委托给上层的commonClassLoader,而是委托给了SystemClassLoader,然后自己加载,最后才委托给commonClassLoader
- 违反双亲委派的例子:Tomcat、JDBC、JNDI、OSGi
http://blog.csdn.net/kyfxbl/article/details/11968751
http://www.cnblogs.com/xing901022/p/4574961.html
tomcat的类加载顺序