这是一篇较早时候写的文章,最近在J道
看到一个与classloader有关的讨论
,于是重新翻出来。
静态库、动态连接库
程
序编制一般需经编辑、编译、连接、加载和运行几个步骤。在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在连接步骤中,连
接器将从库文件取得所需的代码,复制到生成的可执行文件中。这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会
有多份冗余拷贝。
为了克服这个缺点可以采用动态连接库。这个时候连接器仅仅是在可执行文件中打上标志,说明需要使用哪些动态连接库;当运行程序时,加载器根据这些标志把所需的动态连接库加载到内存。
另外在当前的编程
环
境中,一般都提供方法让程序在运行的时候把某个特定的动态连接库加载并运行,也可以将其卸载(例如Win32的
LoadLibrary()&FreeLibrary()和Posix的dlopen()&dlclose())。这个功能被广泛地用于
在程序运行时刻更新某些功能模块或者是程序外观。
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负责加载应用程序自身的类。
When to load the class?
什
么时候JVM会使用ClassLoader加载一个类呢?当你使用java去执行一个类,JVM使用Application
ClassLoader加载这个类;然后如果类A引用了类B,不管是直接引用还是用Class.forName()引用,JVM就会找到加载类A的
ClassLoader,并用这个ClassLoader来加载类B。
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()为父对象。如下图:
在Java 1.2后,java class的加载采用所谓的委托模式(Delegation Modle),当调用一个ClassLoader.loadClass()加载一个类的时候,将遵循以下的步骤:
1)检查这个类是否已经被加载进来了?
2)如果还没有加载,调用父对象加载该类
3)如果父对象无法加载,调用本对象的findClass()取得这个类。
所以当创建自己的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 only 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就会在适当的时候把不会再使用的类卸载。
参考资料及图片来源——Understanding J2EE Application Server Class Loading Architectures
相关推荐
遇到类冲突、类找不到等问题时,可通过设置JVM参数`-verbose:class`来查看类加载的详细信息,或者使用JDK的`jmap -histo`命令分析内存中的类加载情况。 8. **线程安全** 类加载过程中的某些步骤,如加载和初始化...
System.out.println("parent class loader: " + cl.getParent()); cl = cl.getParent(); } ``` 这段代码会打印出当前的类加载器以及它们的父加载器。通常,你会看到AppClassLoader(系统类加载器)、...
本工具是对java class文件进行加密保护的工具!本工具全面支持linux/unix/windows操作系统。 众所周知,java编译后的class文件是一种中间字节字文件, 很容易被反编译工具反编译,而传统的java源代码保护方法基本都是...
创建自定义类加载器通常需要继承`java.lang.ClassLoader`,重写`findClass()`或`loadClass()`方法,从而控制类的查找和加载过程。这使得开发者能够在运行时根据需要加载特定的类,比如从网络、数据库或其他非传统...
本工具是对java class文件进行加密保护防止反编译的工具!本工具全面支持linux/unix/windows操作系统。 继推出v1.0版本后,获得了用户大量的支持与的反馈,我们再次推出本v2.0版,对加密算法进行了更大的改进,安全...
JVM 负责执行 Java 字节码,Java Class Loader 负责加载类文件,而 Java Security Manager 则负责实施安全策略。 Java 安全协议 Java 安全协议是指 Java 平台使用的安全协议,包括 SSL/TLS、HTTPS 等。这些协议...
* Java Class Loader:Java Class Loader 负责加载和管理 Java 类文件。 * Java Native Interface(JNI):JNI 是 Java 平台标准版提供的一种机制,用于将 Java 代码与 native 代码集成。 4.Java 平台标准版的新...
2. Java Class Loader: Class Loader 负责加载和链接 Java 字节码,提供了类加载和解析的功能。 3. Java Native Interface(JNI): JNI 是 Java 平台和 native 代码之间的接口,提供了 Java 和 native 代码之间的...
本手册还涵盖了 Java SE 9 中的其他工具和命令,例如 Java 任务计划器(java)、Java Class Loader(java.lang.ClassLoader)等。 在本手册中,我们将详细介绍每个工具和命令的使用方法、参数设置和示例代码,以...
Java加载器(Loader)是Java虚拟机(JVM)的核心组成部分,主要负责将类的字节码文件加载到JVM中并转换为运行时的数据结构。在深入理解这个概念之前,我们首先要明白Java的类加载机制。Java的类加载过程包括加载、...
Java虚拟机(JVM)的Class文件原理是Java程序运行的基础。Java中的所有类都必须先被装载到JVM中才能被执行,这个过程由JVM内的类装载器(ClassLoader)来完成。类装载器的工作是将类文件从硬盘读取到内存中,使得JVM...
Java的Class类是Java反射机制的核心,它代表了Java中的每一个类和接口。Class类的主要功能是提供关于类的信息,包括类的结构、属性、方法等。以下是对Java Class类的详细说明: 1. **Class类对象的创建**:在Java中...
- `public class Actions { ... }` 主类定义,包含了所有的成员变量和方法。 #### 四、核心方法解析 1. **`init()`**:初始化方法负责加载配置文件、登录系统、初始化参数等基础工作。 - **配置加载**:`load_...
在Java编程语言中,类加载器(Class-Loader)是一个至关重要的组件,它负责加载类到JVM(Java虚拟机)中。这个“class-loader测试工程”可能是一个专门设计用于研究和理解Java类加载机制的项目。在Java中,类加载...
### 动态类加载在Java虚拟机中的应用 #### 概述 动态类加载是Java虚拟机(JVM)的一项核心特性,它为Java平台带来了强大的功能:即能够在运行时安装软件组件。这一机制不仅提高了系统的灵活性,还优化了资源管理。...
The Class Loader Architecture The Java Class File The Java API The Java Programming Language Architectural Tradeoffs Future Trends On the CD-ROM The Resources Page 2 Platform independence Why ...
`Class.forName`实际上依赖于当前线程的上下文类加载器(Context Class Loader)。如果类已经加载,`forName`会直接返回该类的`Class`对象;否则,它会使用当前线程的上下文类加载器来加载类。而`ClassLoader`通常...