- 浏览: 1076675 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
flyfeifei66:
list<bean> bean 中有 list&l ...
freemarker中的list -
BelloVersion:
第五种错误Remote host closed connect ...
客户端如何使用httpclient向https服务器发送数据 -
willxue:
看了半天 前面说的是错的?。。。
反向键索引的原理和用途 -
liulanghan110:
quainter 写道麻烦博主,参数为数组时,paramete ...
MYBATIS 的parameter -
quainter:
麻烦博主,参数为数组时,parameterType怎么写啊?
MYBATIS 的parameter
一,ClassLoader的大体过程
如图:
详解:
虚拟机一启动,会先做一些初始化的动作。一旦初始化动作完成之后,就会产生第一个类别加载器,即所谓的Bootstrap Loader,Bootstrap Loader 是由C++ 所撰写而成,这个Bootstrap Loader所做的初始工作中,除了也做一些基本的初始化动作之外,最重要的就是加载定义在sun.misc 命名空间底下的Launcher.java 之中的ExtClassLoader( 因为是inner class ,所以编译之后会变成Launcher$ExtClassLoader.class) ,并设定其Parent 为null,代表其父加载器为Bootstrap Loader 。然后Bootstrap Loader ,再要求加载定义于sun.misc 命名空间底下的Launcher.java 之中的AppClassLoader( 因为是inner class,所以编译之后会变成Launcher$AppClassLoader.class) ,并设定其Parent 为之前产生的ExtClassLoader 实例。
由以上可以看出,classLoader是由下向上查找,上层的不能向下查找。
二,ClassLoader中类的关系
如图:
详解:
AppClassLoader 和ExtClassLoader 都是URLClassLoader 的子类别。由于它们都是URLClassLoader 的子类别,所以它们也应该有URL 作为搜寻类别档的参考,由原始码中我们可以得知,AppClassLoader 所参考的URL 是从系统参java.class.path 取出的字符串所决定,而java.class.path 则是由我们在执行java.exe 时,利用 –cp 或-classpath 或CLASSPATH 环境变量所决定。
ClassLoader的loadClass代码:
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded //类是否被加载过 Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { //到parentclassloader中去查找(像这个parent还有parent递归方式进行查找) c = parent.loadClass(name, false); } else { //启动类加载器进行加载 c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. //当一直都没有找到时,启动当前类的findClass进行查找 //这个通常也是我们扩展的地方 c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }
三,分析及证明:
可以用最底层的ClassLoader得到某一个类(Test)时,Test.class.getClassLoader()就可知当前类在哪一个层次的ClassLoader下被加载
1,BootStrapClassLoader
Class clazz=Class.forName("java.lang.Object"); System.out.println(clazz.getClassLoader()); //输出为null,因为bootstrap在java中不是类,而是由c++编写的 URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs(); for (int i = 0; i < urls.length; i++) { System.out.println(urls[i].getFile()); }//用这个进行查找bootstrap所加载的是哪些jar包
2,ExtClassLoader
clazz = Class.forName("sun.net.spi.nameservice.dns.DNSNameService"); clazzLoader = clazz.getClassLoader(); System.out.println(" sun.net.spi.nameservice.dns.DNSNameService's loader is " + clazzLoader); //在些可以说明ExtClassLoader所加载的类
3,AppClassLoader
当前工程中class与lib都是用此Loader加载
可以通过ClassLoader.getSystemClassLoader()可以获取到AppClassLoader的
4,DefineClassLoader
可以继承URLClassLoader或ClassLoader
当继承ClassLoader重写findClass()方法,parent会相应是AppClassLoader-->ExtClassLoader-->BootStrapClassLoader
URLClassLoader可以直接设置url即可
问题:
由于自己自定义了一个DefineClassLoader替代了加载ant的ClassLoader,另外添加自己jar包,
但是在执行ant编译时,要执行tools.jar里的javac类,在执行javac这个类时,是处在AppClassLoader
下,找不到我添加的DefineClassLoader的jar包
------------------------------------------------
其他一些相应的操作(参考)
在预设情况下,AppClassLoader的搜寻路径为”.”( 目前所在目录),如果使用-classpath 选项(与-cp 等效),就可以改变AppClassLoader 的搜寻路径,如果没有指定-classpath 选项,就会搜寻环境变量CLASSPATH 。如果同时有CLASSPATH 的环境设定与-classpath 选项,则以-classpath 选项的内容为主,CLASSPATH 的环境设定与-classpath 选项两者的内容不会有加成的效果。至于ExtClassLoader 也有相同的情形,不过其搜寻路径是参考系统参数java.ext.dirsBootstrap Loader ,我们可以经由查询由系统参数sun.boot.class.path 得知Bootstrap Loader 用来搜寻类别的路径java -Dsun.boot.class.path=请回头看到java.class.path 与sun.boot.class.path,也就是说,AppClassLoader 与Bootstrap Loader 会搜寻它们所指定的位置(或JAR 文件),如果找不到就找不到了,AppClassLoader 与Bootstrap Loader 不会递归式地搜寻这些位置下的其他路径或其他没有被指定的JAR 文件。反观ExtClassLoader,所参考的系统参数是java.ext.dirs,意思是说,他会搜寻底下的所有JAR 文件以及classes 目录,作为其搜寻路径(所以您会发现上面我们在测试的时候,如果加入-Dsun.boot.class.path=c:windows 选项时,程序的起始速度会慢了些,这是因为c:windows 目录下的文件很多,必须花额外的时间来列举JAR 文件)。
在命令行下参数时,使用–classpath / -cp / 环境变量CLASSPATH 来更改AppClassLoader 的搜寻路径,或者用 –Djava.ext.dirs 来改变ExtClassLoader的搜寻目录,两者都是有意义的。可是用–Dsun.boot.class.path 来改变Bootstrap Loader 的搜寻路径是无效。这是因为AppClassLoader与ExtClassLoader 都是各自参考这两个系统参数的内容而建立,当您在命令行下变更这两个系统参数之后,AppClassLoader 与ExtClassLoader在建立实例的时候会参考这两个系统参数,因而改变了它们搜寻类别文件的路径; 而系统参数sun.boot.class.path 则是默认与Bootstrap Loader 的搜寻路径相同,就算您更改该系统参与,与BootstrapLoader 完全无关,AppClassLoader 与ExtClassLoader 在整个虚拟机之中只会存有一份,一旦建立了,其内部所参考的搜寻路径将不再改变,也就是说,即使我们在程序里利用System.setProperty() 来改变系统参数的内容,仍然无法更动AppClassLoader 与ExtClassLoader 的搜寻路径。因此,执行时期动态更改搜寻路径的设定是不可能的事情。
参考网址:http://blog.sina.com.cn/s/blog_4efddaed01008ypj.html
http://syue.com/Software/JAVA/15709.html
发表评论
-
JAVA内存分析
2017-09-30 18:42 507jmap -heap pid : 查看堆的使用状况信息 ... -
java dump线程日志
2016-02-15 10:52 1555JVM 自带的工具获取线程堆栈: JDK自带命令行工具获取 ... -
spring 拦截器
2015-05-05 16:07 8771.拦截器配置 <mvc:intercepto ... -
用 ThreadLocal 管理用户session
2014-11-10 15:47 9253很多项目中需要在代码中使用当前登录用户的信息,但是又不方便把 ... -
JAVA并发控制的几种办法
2014-08-25 16:43 2780假如有十张票,现在 ... -
synchronized
2014-08-21 16:58 1298synchronized 关键字的作 ... -
非阻塞同步机制与CAS操作
2014-07-29 16:07 1435锁的劣势 Java ... -
线程简介(转)
2014-04-21 12:06 807一、线程概述 线程是 ... -
什么是线程,如何创建线程
2014-04-21 12:03 972如果你学习过操作系统 ... -
线程池有助于实现最佳资源利用率
2014-04-21 10:01 1476为什么要用线程池? 诸如 Web 服务器、数据库服务器、 ... -
spring实现初始化和销毁bean之前进行的操作
2014-03-03 19:01 1016第一种:通过@PostConstruct 和 @PreDes ... -
文章自动添加超链接
2014-01-14 16:01 2209在网上可以发现,很多文章中的关键词会有超链接,超链接的实现 ... -
JVM 内存监控
2013-11-28 14:17 1083jps Java进程查看工具,实际上它和Unix/Lin ... -
freemarker操作字符串,数字,布尔类型函数
2013-11-26 16:45 6691布尔类型 1. 后台不能将值设置为Boolean对 ... -
汉字转拼音
2013-11-26 16:39 1242import net.sourceforge.pinyin4 ... -
birt读取现有系统的数据库配置作为数据源
2013-09-10 13:51 3865Birt的数据源可以用多种形式,当我们把BIRT嵌入到现有 ... -
birt动态SQL
2013-07-26 18:05 9119birt动态SQL实现有三种方式:拼接SQL、绑定变量和让 ... -
关于spring事务
2013-06-13 14:44 1021在ORACLE数据库中,一般DDL语句是隐式COMMIT提交 ... -
Tomcat Server是如何处理http请求的
2013-05-08 10:24 1336假设来自客户的请求为:http://localhost:8 ... -
注解annotation
2013-05-07 14:40 1128ava注解是附加在代码中的一些元信息,用于一些工具在编译、运 ...
相关推荐
Java ClassLoader是Java...链接过程包括验证、准备和解析阶段,这些是类加载到JVM中的关键步骤。此外,了解类加载器的层次结构也很重要,Java标准类加载器有Bootstrap ClassLoader、Extension ClassLoader和AppClassL
定制ClassLoader的过程中,需要注意以下几点: 1. 安全性:自定义ClassLoader可能导致安全问题,因为它可以加载任意的类,因此需要确保加载的类是可信的。 2. 类的可见性:不同的ClassLoader加载的类相互之间默认是...
因此,当创建自定义Classloader时,必须谨慎处理类的加载过程,避免加载未经验证的代码。 八、优化与性能 在实现自定义Classloader时,要注意性能问题。过度复杂的加载逻辑可能导致性能下降。同时,避免不必要的...
在类加载过程中,如果没有在当前ClassLoader的缓存中找到类,ClassLoader会按照上述顺序逐级向上查找。例如,假设有一个名为A的类,加载顺序如下: 1. 如果WebApp ClassLoader的缓存中没有类A,则会查找System ...
- 示例可能还涉及到了对异常处理的演示,因为自定义加载过程中可能会遇到找不到类或非法类文件的问题。 了解和掌握ClassLoader的概念及其应用,对于理解和调试复杂的Java应用程序,尤其是涉及到动态加载和插件化...
`ClassLoader`不仅管理着类的加载过程,而且其设计模式还对Java的安全性和性能有着至关重要的影响。 #### 二、类的生命周期与加载阶段 类的生命周期包括加载、验证、准备、解析、初始化五个阶段。其中,加载阶段是...
这个过程可以通过自定义ClassLoader来实现,比如从数据库中加载类。 2. **验证**:验证是确保加载的类符合Java语言规范,不会破坏JVM的安全性。它检查字节码的格式、数据流和操作符计算、类和字段的访问控制等。 3...
Java应用程序的运行离不开类的加载,而ClassLoader正是这个过程的关键角色。它负责将类的字节码加载到Java虚拟机(JVM)中并转换为可执行的Java对象。深入理解ClassLoader的工作原理对于优化应用性能、解决类加载...
在反射过程中,如果没有加载目标类,那么会触发ClassLoader的加载机制。 总结,理解ClassLoader的加载机制和原理对于优化程序性能、设计可扩展的系统至关重要。通过自定义ClassLoader,开发者可以实现许多高级功能...
ClassLoader不仅负责类的加载,还涉及类的验证、初始化等一系列过程。理解ClassLoader的工作原理对于优化Java应用程序性能以及解决类冲突等问题具有重要意义。 一、ClassLoader的基本概念 Java程序由多个类组成,...
首先,ClassLoader可以分为三种基本类型:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。Bootstrap ClassLoader是JVM启动时的第一个ClassLoader,负责加载JDK的`<JAVA_HOME>\lib`目录下...
这个过程可能涉及字节码验证,确保类的安全性。 3. **链接**:链接阶段包括三个子步骤:验证、准备和解析。验证确保字节码符合JVM规范;准备阶段为类的静态变量分配内存并初始化它们的默认值;解析阶段将符号引用...
Java中的类加载过程分为三个阶段:加载、验证、准备、解析和初始化。默认情况下,系统使用Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader来加载不同路径下的类。自定义ClassLoader则允许我们插入这...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中执行。这篇测试主要探讨了ClassLoader的工作原理及其在实际应用中的使用。通过阅读给出的博文链接,我们可以深入理解...
这个过程通常涉及到从文件系统或网络中查找资源。找到后,ClassLoader会解析字节码并创建Class对象,然后进行验证,确保代码的安全性。 在Java中,用户可以通过自定义ClassLoader来实现特定的加载逻辑,比如从...
Java的类加载过程遵循双亲委托模型,即一个类加载请求会先委托给父ClassLoader,只有当父类加载器无法完成加载时,才会由当前类加载器进行加载。 ClassLoader的工作流程可以分为三个主要步骤: 1. **查找**:当...