[转]java classLoader 体系结构
这篇文章介绍classLoader算是比较详细了,顺手转来了。为后天的Google笔试,这两天拼命看啊- -
版权信息: 可以任意转载, 转载时请务必以超链接形式标明文章原文出处, 即下面的声明.
原文出处:http://blog.chenlb.com/2009/06/java-classloader-architecture.html
jvm classLoader architecture:
- Bootstrap ClassLoader/启动类加载器
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。 - Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。 - System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。 - User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。
类加载器的特性:
- 每个ClassLoader都维护了一份自己的名称空间, 同一个名称空间里不能出现两个同名的类。
- 为了实现java安全沙箱模型顶层的类加载器安全机制, java默认采用了 " 双亲委派的加载链 " 结构。
classloader-architecture
classloader-class-diagram
类图中, BootstrapClassLoader是一个单独的java类, 其实在这里, 不应该叫他是一个java类。因为,它已经完全不用java实现了。它是在jvm启动时, 就被构造起来的, 负责java平台核心库。
自定义类加载器加载一个类的步骤
classloader-load-class
ClassLoader 类加载逻辑分析, 以下逻辑是除 BootstrapClassLoader 外的类加载器加载流程:
- // 检查类是否已被装载过
- Class c = findLoadedClass(name);
- if (c == null ) {
- // 指定类未被装载过
- try {
- if (parent != null ) {
- // 如果父类加载器不为空, 则委派给父类加载
- c = parent.loadClass(name, false );
- } else {
- // 如果父类加载器为空, 则委派给启动类加载加载
- c = findBootstrapClass0(name);
- }
- } catch (ClassNotFoundException e) {
- // 启动类加载器或父类加载器抛出异常后, 当前类加载器将其
- // 捕获, 并通过findClass方法, 由自身加载
- c = findClass(name);
- }
- }
线程上下文类加载器
java默认的线程上下文类加载器是 系统类加载器(AppClassLoader)。
- // Now create the class loader to use to launch the application
- try {
- loader = AppClassLoader.getAppClassLoader(extcl);
- } catch (IOException e) {
- throw new InternalError(
- "Could not create application class loader" );
- }
- // Also set the context class loader for the primordial thread.
- Thread.currentThread().setContextClassLoader(loader);
以上代码摘自sun.misc.Launch的无参构造函数Launch()。
使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.
典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.
大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。
还有一些采用 hotswap 特性的框架, 也使用了线程上下文类加载器, 比如 seasar (full stack framework in japenese).
线程上下文从根本解决了一般应用不能违背双亲委派模式的问题.
使java类加载体系显得更灵活.
随着多核时代的来临, 相信多线程开发将会越来越多地进入程序员的实际编码过程中. 因此,
在编写基础设施时, 通过使用线程上下文来加载类, 应该是一个很好的选择。
当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个,
防止因为不同的类加载器, 导致类型转换异常(ClassCastException)。
为什么要使用这种双亲委托模式呢?
- 因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
- 考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的ClassLoader。
java动态载入class的两种方式:
- implicit隐式,即利用实例化才载入的特性来动态载入class
- explicit显式方式,又分两种方式:
- java.lang.Class的forName()方法
- java.lang.ClassLoader的loadClass()方法
用Class.forName加载类
Class.forName使用的是被调用者的类加载器来加载类的。
这种特性, 证明了java类加载器中的名称空间是唯一的, 不会相互干扰。
即在一般情况下, 保证同一个类中所关联的其他类都是由当前类的类加载器所加载的。
- public static Class forName(String className)
- throws ClassNotFoundException {
- return forName0(className, true , ClassLoader.getCallerClassLoader());
- }
- /** Called after security checks have been made. */
- private static native Class forName0(String name, boolean initialize,
- ClassLoader loader)
- throws ClassNotFoundException;
上面中 ClassLoader.getCallerClassLoader 就是得到调用当前forName方法的类的类加载器
static块在什么时候执行?
- 当调用forName(String)载入class时执行,如果调用ClassLoader.loadClass并不会执行.forName(String,false,ClassLoader)时也不会执行.
- 如果载入Class时没有执行static块则在第一次实例化时执行.比如new ,Class.newInstance()操作
- static块仅执行一次
各个java类由哪些classLoader加载?
- java类可以通过实例.getClass.getClassLoader()得知
- 接口由AppClassLoader(System ClassLoader,可以由ClassLoader.getSystemClassLoader()获得实例)载入
- ClassLoader类由bootstrap loader载入
NoClassDefFoundError和ClassNotFoundException
- NoClassDefFoundError:当java源文件已编译成.class文件,但是ClassLoader在运行期间在其搜寻路径load某个类时,没有找到.class文件则报这个错
- ClassNotFoundException:试图通过一个String变量来创建一个Class类时不成功则抛出这个异常
参考:
- 重温java之classloader体系结构(含hotswap)
- classloader相关基础知识
其它相关 classloader:
- [笔记]类加载器
- 深入了解Java ClassLoader、Bytecode 、ASM、cglib
- 解读ClassLoader
转载于:https://www.cnblogs.com/shadowofs/archive/2011/10/11/2207721.html
[转]java classLoader 体系结构相关推荐
- Java ClassLoader详解
翻译原文链接 背景 Java平台旨在提供健壮,安全和可扩展的功能,以支持代码和数据的移动性.Java虚拟机(JVM)中的Java ClassLoader是实现这些目标的关键组件. JVM负责在Java ...
- Java内存体系结构(模型),垃圾回收和内存泄漏
Java内存架构(Java内存模型) 上面是堆的Java内存模型以及Java虚拟机(JVM)中运行的任何Java应用程序的PermGen. 还提供了比率,以使您更好地了解如何在每种世代类型之间分配允许 ...
- Java IO 体系结构
参考文章地址: http://blog.csdn.net/oracle_microsoft/article/details/2634231 Java IO体系结构看似庞大复杂,其实有规律可循,要弄清楚 ...
- Java异常体系结构
一. 异常的概念和Java异常体系结构 异常是程序运行过程中出现的错误.本文主要讲授的是Java语言的异常处理.Java语言的异常处理框架, 是Java语言健壮性的一个重要体现. Java把 ...
- java异常体系结构详解
java异常体系结构详解 参考文章: (1)java异常体系结构详解 (2)https://www.cnblogs.com/hainange/p/6334042.html 备忘一下.
- [转载] 深入了解Java ClassLoader、Bytecode 、ASM、cglib
转载自http://www.iteye.com/topic/98178 一.Java ClassLoader 1,什么是ClassLoader 与 C 或 C++ 编写的程序不同,Java 程序并不 ...
- Java ClassLoader
Java ClassLoader (1) – What is a ClassLoader? Java ClassLoader (2) – Write your own ClassLoader Java ...
- 深入理解Java ClassLoader及在 JavaAgent 中的应用
转载自 深入理解Java ClassLoader及在 JavaAgent 中的应用 背景 众所周知, Java 或者其他运行在 JVM(java 虚拟机)上面的程序都需要最终便以为字节码,然后被 ...
- 了解和扩展Java ClassLoader
Java ClassLoader是项目开发中Java的关键但很少使用的组件之一. 就我个人而言,我从未在任何项目中扩展ClassLoader,但是拥有自己的可以自定义Java类加载的ClassLoad ...
- java面试题28 牛客 下面有关java classloader说法错误的是?
java面试题28 牛客 下面有关java classloader说法错误的是? A Java默认提供的三个ClassLoader是BootStrap ClassLoader,Extension Cl ...
最新文章
- 进程的用户栈和内核栈
- 浅谈常见的七种加密算法及实现(附代码)
- 在预加载新闻时,怎么去掉初始化内容的显示尴尬?
- Python基础——PyCharm版本——第八章、文件I/O(核心3、csv和excel解析)
- SystemVerilog声明的位置
- 手把手教你用Python求最大值和最小值
- 面对 10 亿数据量的挑战,如何对系统进行性能优化?
- 量化投资与Python
- 7月28日吃鸡端游服务器维护,绝地求生7月28日维护到什么时候结束
- 基于国土“三调”成果的自然资源开发利用和保护的综合研究
- Windows Server 2008 R2 下载地址
- 使用group by查询时报错ORDER BY clause is not in GROUP BY..this is incompatible with sql_mode=only_full_grou
- python检测刀具_科研一角|Python语言在人工智能加工中心机器人方面的应用
- nginx中的sub_filter
- 2019年寒假 纪中培训总结
- 烟雨白银坨_SAP刘梦_新浪博客
- 计算机专业英语词组,计算机专业英语词组.doc
- 自制 C++ 密码程序(第二代)
- 2021年总结以及2022年的计划
- python perl r_PHP Python Ruby Perl
热门文章
- 【转载好文】对char *和char []做形参的深入理解+const char*/char const*/char *const的解析
- java 设计模式 抽象工厂_Java设计模式----------抽象工厂模式
- python3.5.4安装_linux-centos系统下安装python3.5.4步骤
- java中charconst_C语言常量
- 在线工具:找到神器,助你轻松应对各种职场难题
- 倒排索引Inverted index
- 在排序数组中查找数字
- 技校学计算机和本科计算机,中专计算机专业学什么,中专和技校的区别​
- java语言没有保留结构和联合,java选择题判断题题库.doc
- Playing Atari with Deep Reinforcement Learning 中文 讲解3