`

关于ClassLoader的几个概念

    博客分类:
  • Java
阅读更多
What is ClassLoader?

与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。

JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,Bootstrap ClassLoader是用本地代码实现的,它负责加载核心Java Class(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由Bootstrap ClassLoader加载;其中Extension ClassLoader负责加载扩展的Java class(例如所有javax.*开头的类和存放在JRE的ext目录下的类),Application ClassLoader负责加载应用程序自身的类。

当运行一个程序的时候,JVM启动,运行bootstrap classloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加 载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一 个程序最基本的加载流程。

注: 学ClassLoader看OSGI

When to load the class?

什么时候JVM会使用ClassLoader加载一个类呢?当你使用java去执行一个类,JVM使用Application ClassLoader加载这个类;然后如果类A引用了类B,不管是直接引用还是用Class.forName()引用,JVM就会找到加载类A的 ClassLoader,并用这个ClassLoader来加载类B。JVM按照运行时的有效执行语句,来决定是否需要装载新类,从而装载尽可能少的类, 这一点和编译类是不相同的。


Why use your own ClassLoader?

似乎JVM自身的ClassLoader已经足够了,为什么我们还需要创建自己的ClassLoader呢?

因为JVM自带的ClassLoader只是懂得从本地文件系统加载标准的java class文件,如果编写你自己的ClassLoader,你可以做到:
1)在执行非置信代码之前,自动验证数字签名
2)动态地创建符合用户特定需要的定制化构建类
3)从特定的场所取得java class,例如数据库中
4) 等等

事实上当使用Applet的时候,就用到了特定的ClassLoader,因为这时需要从网络上加载java class,并且要检查相关的安全信息。

目前的应用服务器大都使用了ClassLoader技术,即使你不需要创建自己的ClassLoader,了解其原理也有助于更好地部署自己的应用。

ClassLoader Tree & Delegation Model

当你决定创建你自己的ClassLoader时,需要继承java.lang.ClassLoader或者它的子类。在实例化每个 ClassLoader对象时,需要指定一个父对象;如果没有指定的话,系统自动指定 ClassLoader.getSystemClassLoader()为父对象。


所以当创建自己的Class Loader时,只需要重载findClass()这个方法。

Unloading? Reloading?

当一个java class被加载到JVM之后,它有没有可能被卸载呢?我们知道Win32有FreeLibrary()函数,Posix有dlclose()函数可以被 调用来卸载指定的动态连接库,但是Java并没有提供一个UnloadClass()的方法来卸载指定的类。

在Java中,java class的卸载仅仅是一种对系统的优化,有助于减少应用对内存的占用。既然是一种优化方法,那么就完全是JVM自行决定如何实现,对Java开发人员来说是完全透明的。

在什么时候一个java class/interface会被卸载呢?Sun公司的原话是这么说的:"class or interface may be unloaded if and on
ly if its class loader is unreachable. Classes loaded by the bootstrap loader may not be unloaded."

事实上我们关心的不是如何卸载类的,我们关心的是如何更新已经被加载了的类从而更新应用的功能。JSP则是一个非常典型的例子,如果一个JSP文件被更改了,应用服务器则需要把更改后的JSP重新编译,然后加载新生成的类来响应后继的请求。

其实一个已经加载的类是无法被更新的,如果你试图用同一个ClassLoader再次加载同一个类,就会得到异常 (java.lang.LinkageError: duplicate class definition),我们只能够重新创建一个新的ClassLoader实例来再次加载新类。至于原来已经加载的类,开发人员不必去管它,因为它可能 还有实例正在被使用,只要相关的实例都被内存回收了,那么JVM就会在适当的时候把不会再使用的类卸载。


使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.
典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.
大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。

当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个, 防止因为不同的类加载器, 导致类型转换异常(ClassCastException).
参考资料及图片来源——Understanding J2EE Application Server Class Loading Architectures

http://www.jdon.com/jivejdon/thread/15456.html
http://gceclub.sun.com.cn/yuanchuang/week-9/classloader.html
分享到:
评论

相关推荐

    ClassLoader

    #### 一、ClassLoader概念与作用 在Java编程语言中,`ClassLoader`是一个非常重要的组件,它负责加载程序运行所需的类文件到Java虚拟机(JVM)中。`ClassLoader`不仅管理着类的加载过程,而且其设计模式还对Java的...

    java classloader classpath 张孝祥

    `ClassLoader`提供了两个重要的方法用于资源定位: - `public URL getResource(String name)`:返回一个`URL`对象,表示名为`name`的资源。 - `public InputStream getResourceAsStream(String name)`:返回一个...

    Understanding the Java ClassLoader

    Java中的ClassLoader分为几种类型,形成了一个层次结构: - **Bootstrap ClassLoader**:这是根ClassLoader,用于加载核心类库,如java.lang.*等。 - **Extension ClassLoader**:这个ClassLoader加载Java扩展包中...

    j-classloader-ltr

    1. **继承`java.lang.ClassLoader`类**:创建一个新的类,该类继承自`java.lang.ClassLoader`。 2. **重写`findClass`方法**:在这个方法中,实现如何从特定位置加载类文件。 3. **处理字节码**:加载类文件后,需要...

    Tomcat研究之ClassLoader.pdf

    其ClassLoader体系结构可以分为以下几个层次: 1. **Bootstrap ClassLoader**:这是JVM自带的类加载器,负责加载JVM自带的核心类库以及`$JAVA_HOME/jre/lib/ext/*.jar`目录下的扩展类库。 2. **System ...

    java自定义类加载classloader文档,包括代码

    上述代码展示了如何创建一个自定义类加载器`MyClassLoader`,该类继承自`java.lang.ClassLoader`。`MyClassLoader`的主要功能是从文件系统中加载指定类的二进制数据。 - **构造函数**:接受一个父类加载器和基础...

    测试普通Java程序ClassLoader等级关系的Demo程序

    在"Test"这个Demo程序中,可能包含了几种测试用例,用于演示不同ClassLoader如何加载类,以及它们之间的协作关系。例如,可能会创建自定义的ClassLoader子类,然后尝试加载一个类,观察加载顺序和结果。这些测试用例...

    Tomcat 5.0.18 ClassLoader source code insight

    首先,我们来看ClassLoader的基本概念。在Java中,ClassLoader是动态加载类的机制,它遵循双亲委派模型。当一个类加载器收到加载类的请求时,它首先会委托给父加载器,只有当父加载器无法加载时,才会尝试自己加载。...

    java classloader讲义-淘宝网

    ### Java ClassLoader详解:以淘宝网为例...以上内容详细介绍了Java ClassLoader的基本概念、工作原理、自定义方式及其实战应用,并结合淘宝网的实际案例进行了分析,希望能够帮助读者更深入地理解和运用ClassLoaders。

    tomcat 类加载机制 —— ClassLoader

    首先,理解类加载器(ClassLoader)的基本概念是必要的。ClassLoader是Java运行时环境的一部分,负责查找并加载Java类到JVM中。在Java中,类的加载、验证、解析和初始化都是由ClassLoader来完成的。Tomcat作为一个...

    浅谈java中的四个核心概念

    Java API分为以下几个部分: 1. **标准API**:这是Java最基础的部分,包括了核心类库,如`java.lang`、`java.util`等。 2. **扩展API**:这部分API通常包含在扩展包中,例如`javax.*`包,它们提供了更多的高级功能...

    classloader类加载器_基于java类的加载方式详解

    当我们谈论Java类加载器时,通常涉及到几个核心的概念: 1. Bootstrap ClassLoader(启动类加载器):这是最顶层的类加载器,由C++编写,是JVM自身的一部分。它负责加载存放在JAVA_HOME/lib目录或-Xbootclasspath...

    JVM原理.doc

    JVM的物理结构可以分为以下几个部分: 1. 类加载器(ClassLoader)系统,包括Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader,它们分别负责加载基础类库、扩展类库和用户指定的类路径中的类。 2. ...

    java杂谈-一个计算机专业学生几年的编程经验汇总谈.pdf

    Java编程语言是计算机科学中的一个重要组成部分,尤其对于计算机专业的学生来说,掌握Java的基础和高级概念至关重要。本文主要围绕Java的一些核心概念进行讨论,旨在帮助读者更好地理解和应用Java。 首先,我们来看...

    Java常问到的几个中级以上问题

    方法的隐藏和覆盖是面向对象中的两个重要概念: - 方法覆盖(Override):当子类重写父类中非静态的同名方法时,若方法签名完全一致,那么子类的方法就会覆盖父类的方法。在多态调用中,会调用子类覆盖后的方法。 ...

    java基础1

    `ClassLoader`类提供了几个关键方法用于类的加载和管理,如: 1. `loadClass(String className)`:这是加载类的主要方法,会递归地调用父加载器尝试加载类,如果没有找到,则由当前加载器加载。 2. `findClass...

    java类加载器-tomcat中的类加载器

    在Java中,类加载器主要分为三个层次:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader。Bootstrap ClassLoader负责加载JDK的核心库,如rt.jar;Extension ClassLoader则加载JRE扩展目录下的jar文件...

Global site tag (gtag.js) - Google Analytics