[Java]ClassLoader
2014-06-09 11:34
225 查看
在Java程序员的角度来看有三种类加载器:
bootstrap:加载JAVA_HOME/lib目录下的类
extension:加载JAVA_HOME/lib/ext目录下的类
application:加载classpath指定目录中的类
在JVM中,根据ClassLoader来决定是不是同一个类,从这个角度来看,ClassLoader的作用类似namespace,也就是说可以利用ClassLoader对Class进行隔离。而如果这么用可能就要破坏双亲委派模式了。
初始类装载器:如果要求A去装载一个类型,而A返回了B装载的类型,那么A为就是初始类装载器。
定义类装载器:B是定义类装载器。
如果某个类加载器把加载的任务委派给另一个类加载器,而后者定义了这个类型,那么被委派的类加载器装载的这个类型,在所有被记为该类型的初始类装载器的命名空间中共享。
----------END----------
bootstrap:加载JAVA_HOME/lib目录下的类
extension:加载JAVA_HOME/lib/ext目录下的类
application:加载classpath指定目录中的类
在JVM中,根据ClassLoader来决定是不是同一个类,从这个角度来看,ClassLoader的作用类似namespace,也就是说可以利用ClassLoader对Class进行隔离。而如果这么用可能就要破坏双亲委派模式了。
双亲委派
从代码里面看双亲委派模型更直观些:protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{ // 首先检查是否加载过该类 Class c = findLoadedClass(name); if (c == null) { // 先让parent去加载 try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { } // 如果parent没有加载到,自己再去加载 if (c == null) { c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }自己定义ClassLoader的话可以实现findClass方法:
protected Class<?> findClass(String name) { // 加载不是我们关心的类时,按照原来的逻辑走 if (name.startsWith("java")) { try { return super.loadClass(name); } catch (ClassNotFoundException e) { } } // 从dir/XXX.class文件读取数据 byte[] data = loadClassData(name); // 根据byte[]生成Class return defineClass(name, data, 0, data.length); }下面对自己写的ClassLoader进行测试:
public class Main { public static void main(String[] args) throws Exception { MyClassLoader loaderA = new MyClassLoader(); MyClassLoader loaderB = new MyClassLoader(); Class<?> classA = loaderA.findClass("TestClass"); Class<?> classB = loaderB.findClass("TestClass"); System.out.println(classA == classB);// false } }可以看到不同的两个ClassLoader加载相同的Class,在JVM中判断为不是同一个类。这样可能导致一个问题:用Grovy等工具的时候用ClassLoader加载类,可能会有大量的ClassLoader加载大量的类并没有被及时回收导致OOM。
命名空间
由不同的类装载器加载的类被放在虚拟机内部不同的命名空间中。同一个命名空间中的类可以直接进行交互,而不会感知到另一个命名空间中类的存在。这里有两个概念:初始类装载器:如果要求A去装载一个类型,而A返回了B装载的类型,那么A为就是初始类装载器。
定义类装载器:B是定义类装载器。
如果某个类加载器把加载的任务委派给另一个类加载器,而后者定义了这个类型,那么被委派的类加载器装载的这个类型,在所有被记为该类型的初始类装载器的命名空间中共享。
----------END----------
相关文章推荐
- 深入了解Java ClassLoader,Bytecode,ASM,Cglib
- 了解 JAVA classloader
- 深入了解Java ClassLoader、Bytecode 、ASM、cglib
- Java的ClassLoader与Package机制
- java classLoader 原则
- 深入了解Java ClassLoader、Bytecode 、ASM、cglib
- Java的ClassLoader与Package机制
- 理解Java ClassLoader机制 (转载http://www.blogjava.net/pandawang/archive/2006/08/20/64639.html)
- java用URLClassLoader动态加载JDBC
- Java的ClassLoader与Package机制
- 用URLClassLoader 在java运行期间jar文件动态载入类
- 关于Java ClassLoader的(转载Richard Li )
- 了解 JAVA classloader
- 理解Java ClassLoader机制
- Java ClassLoader 实现程序的扩展性
- JAVA的类装载器(ClassLoader)
- 探讨JavaClassLoader与Package机制
- java的ClassLoader
- 深入了解Java ClassLoader、Bytecode 、ASM、cglib
- java classLoader 原则