锁定老帖子 主题:jvm classloader
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-02
最后修改:2010-09-03
1. 从一个简单小实验开始: (1) Eclipse下建一简单Java project,写一个简单程序,如下: package com.javaeye.loader; public class URLClassLoaderTest { public void show() { System.out.println("I am running..."); } }
(2) 到项目对应bin/com/javaeye/loader下找到URLClassLoaderTest.class文件,将此文件保存,然后删除整个project; (3) 在磁盘任何位置建立文件夹com,在com里建立javaeye,在javaeye里建立loader,我建在C盘java目录下,建立完成后将(2)中保存的URLClassLoaderTest.class文件拷贝到其中,如下:
@Test public void testInWeb() throws Exception{ URL[] urls = new URL[]{new URL("http://192.168.66.250/root/java/")}; URLClassLoader loader = new URLClassLoader(urls); Class clas = loader.loadClass("com.javaeye.loader.URLClassLoaderTest"); Method m = clas.getMethods()[0]; Object o = clas.newInstance(); m.invoke(o); } @Test public void testInFileSystem() throws Exception{ URL[] urls = new URL[]{new URL("file:/C:/java/")}; URLClassLoader loader = new URLClassLoader(urls); Class clas = loader.loadClass("com.javaeye.loader.URLClassLoaderTest"); Method m = clas.getMethods()[0]; Object o = clas.newInstance(); m.invoke(o); } 分别运行两端代码他们输出结果都是: I am running... 分析: 为什么会出现上述运行结果,很明显是因为com.learn.loader.URLClassLoaderTest对象被加载到内存,此对象中的show方法被执行; 思考: Java 语言由于在 Java 虚拟机 (JVM) 上运行而显得与众不同,之所以与众不同是因为Java中已编译的程序是一种特殊的、独立于平台的格式,并非依赖于它们所运行的机器。在很大程度上,这种格式不同于传统的可执行程序格式。与 C 或 C++ 编写的程序不同,Java 程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件对应于一个 Java 类。此外,这些类文件并非立即全部都装入内存,而是根据程序需要装入内存。ClassLoader 是 JVM 中将类装入内存的工具。
2.jvm classLoader architecture 同样给出一个例子代码: public void testClassLoader2() throws Exception{ URL[] urls = new URL[]{new URL("http://192.168.66.250/root/java/")}; URLClassLoader loader = new URLClassLoader(urls); System.out.println(loader.getClass()); System.out.println(loader.getParent().getClass()); System.out.println(loader.getParent().getParent().getClass()); System.out.println(loader.getParent().getParent().getParent()); }
运行结果如下: class java.net.URLClassLoader class sun.misc.Launcher$AppClassLoader class sun.misc.Launcher$ExtClassLoader null
要解释这个运行结果需要说明jvm classloader 结构,如下图:
最底层:User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类) ,在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。显然java.net.URLClassLoader属于此层; AppClassLoader层:System ClassLoader/系统类加载器,主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。java.lang.ClassLoader.getSystemClassLoader()可以得到他,上述sun.misc.Launcher$AppClassLoader属于此层; ExtClassloader层:Extension ClassLoader/扩展类加载器,主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作,sun.misc.Launcher$ExtClassLoader属于此层; 最顶层:Bootstrap ClassLoader/启动类加载器,主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作,为什么对应这层输出为null?是因为Bootstrap是用C++编写的,我们在Java中看不到它,是null;
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-09-02
这文章不错,解答了我不少疑问。
我之前一直没有把javase的classloader 分成三~四个层次来看, 现在这样一解释,这个层次就分明多了, 对于以前没有留意到的jvm参数也明白多了。 thanks LZ very much by 1000 times. je竟不能用中文写上面的这段东西,哈哈,笑死我了 |
|
返回顶楼 | |
发表时间:2010-09-03
楼主大大文章的后半段好像跟另一位大大写的一样呀,重温java之classloader体系结构(含hotswap)
|
|
返回顶楼 | |
发表时间:2010-09-03
最后修改:2010-09-03
有个问题啊 ?????
你的class的# package com.learn.loader; 那么 loadClass("com.javaeye.loader.URLClassLoaderTest"); 不需要对应的是 loadClass("com.learn.loader.URLClassLoaderTest");吗??? |
|
返回顶楼 | |
发表时间:2010-09-03
congdepeng 写道 有个问题啊 ?????
你的class的# package com.learn.loader; 那么 loadClass("[color=red] com.javaeye.loader[/color].URLClassLoaderTest"); 不需要对应的是 loadClass("com.learn.loader.URLClassLoaderTest");吗??? 之前做实验URLClassLoaderTest是在 com.javaeye.loader里,因为只需要URLClassLoaderTest.class,所以之前写的类删掉了,后来写博客时为了还远之前代码所以重写了一下,所以出现逆上述描述,现已经修改... |
|
返回顶楼 | |
发表时间:2010-09-03
引用 为了实现java安全沙箱模型顶层的类加载器安全机制, java默认采用了 " 双亲委派的加载链 " 结构 双亲委派?
|
|
返回顶楼 | |
发表时间:2010-09-04
" 双亲委派的加载链 " 结构 是什么意思??没讲清楚
|
|
返回顶楼 | |
发表时间:2010-10-26
gstarwd 写道 " 双亲委派的加载链 " 结构 是什么意思??没讲清楚
子加载器会询问父类加载器是否能加载当前class,直到问完基类,如果他门都不能加载就由自己加载。。说白了就是先委派父亲加载。 |
|
返回顶楼 | |
发表时间:2010-11-02
fantasy 写道 gstarwd 写道 " 双亲委派的加载链 " 结构 是什么意思??没讲清楚
子加载器会询问父类加载器是否能加载当前class,直到问完基类,如果他门都不能加载就由自己加载。。说白了就是先委派父亲加载。 什么情况下会出现父类加载器不能加载当前class? |
|
返回顶楼 | |
发表时间:2010-11-02
sambean 写道 fantasy 写道 gstarwd 写道 " 双亲委派的加载链 " 结构 是什么意思??没讲清楚
子加载器会询问父类加载器是否能加载当前class,直到问完基类,如果他门都不能加载就由自己加载。。说白了就是先委派父亲加载。 什么情况下会出现父类加载器不能加载当前class? 当子类class文件和父类class文件不在同一台JVM时,比如,在你计算机上加载运程计算机上编译好的class文件,类加载器是Local JVM,而当前Class在 运程计算机上 |
|
返回顶楼 | |