`
wangyanlong0107
  • 浏览: 502702 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

【转】class loader 1

 
阅读更多

What is ClassLoader?

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

  Bootstrap ClassLoader (Extension ClassLoader, ApplicationClassLoader)

JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,BootstrapClassLoader是用本地代码(是用C++编写的)实现的,它负责加载核心JavaClass(即所有java.*开头的类)。,我们在Java中看不到它,是null,是JVM自带的类装载器,用来装载核心类库,如java.lang.*等

另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由BootstrapClassLoader加载;其中Extension ClassLoader负责加载扩展的Javaclass(例如所有javax.*开头的类和存放在JRE的ext目录下的类),ApplicationClassLoader负责加载应用程序自身的类。

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

(1)首先加载核心API,让系统最基本的运行起来

(2)加载扩展类

(3)加载用户自定义的类

 

publicstatic void main(String[] args) {

 

System.out.println(System.getProperty("sun.boot.class.path"));

System.out.println(System.getProperty("java.ext.dirs"));

System.out.println(System.getProperty("java.class.path"));

}

 

程序结果为:

E:\Myeclipse6.0\jre\lib\rt.jar;E:\Myeclipse 6.0\jre\lib\i18n.jar;E:\Myeclipse6.0\jre\lib\sunrsasign.jar;E:\MyEclipse6.0\jre\lib\JSse.jar;E:\MyEclipse 6.0\jre\lib\jce.jar;E:\MyEclipse6.0\jre\lib\charsets.jar;E:\MyEclipse 6.0\jre\classes

E:\MyEclipse6.0\jre\lib\ext

E:\workspace\ClassLoaderDemo\bin

 

在上面的结果中,你可以清晰看见三个ClassLoader分别加载类的路径;也知道为什么我们在编写程序的时候,要把用到的jar包放在工程的classpath下面啦,也知道我们为什么可以不加载java.lang.*包啦!其中java.lang.*就在rt.jar包中;

When to load the class?

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

 

ClassLoader的加载机制

"双亲委托" 加载模式

 

自定义一个URL类:

packagejava.net;

publicclass URL {

privateString path;

publicURL(String path) {

this.path= path;

}

publicString toString() {

returnthis.path + " new Path";

}

}

在这种情况下,系统会提示我们出现异常,因为我们有两个相同的类,一个是真正的URL,一个是我在上面实现的伪类;出现异常是正常的,因为你想想,如果我们在执行一个applet的时候,程序自己实现了一个String的类覆盖了我们虚拟机上面的真正的String类,那么在这个String里面,不怀好意的人可以任意的实现一些功能;这就造成极不安全的隐患;所以java采用了一种名为“双亲委托”的加载模式;

packagejava.net;

importjava.net.*;

publicclass TheSameClsDemo {

publicstatic void main(String[] args) {

URLurl = new URL("http://www.baidu.com");

System.out.println(url.toString());

}

}

以下是jdk源代码:

 

protectedsynchronized Class<?> loadClass(String name, boolean resolve)

throwsClassNotFoundException

{

//First, check if the class has already been loaded

Classc = findLoadedClass(name);

if(c == null) {

try{

if(parent != null) {

c= parent.loadClass(name, false);

}else {

c= findBootstrapClass0(name);

}

}catch (ClassNotFoundException e) {

//If still not found, then invoke findClass in order to find theclass.

c= findClass(name);

}

}

if(resolve) {

resolveClass(c);

}

returnc;

}

 

 

在上面的代码中,我们可以清晰的看见,我们调用一个ClassLoader加载程序的时候,这个ClassLoader会先调用设置好的parentClassLoader来加载这个类,如果parentnull的话,则默认为BootClassLoader类,只有在parent没有找的情况下,自己才会加载,这就避免我们重写一些系统类,来破坏系统的安全;

 

类与它所依赖的类的classloader机制:

如果一个类是由某个classloader加载,那么这个类依赖的类(非显式的通过某个classloader加载)必须也由该classloader或其父classloader加载,无视子classloader

 

Unloading?

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

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

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

Reloading?

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

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

  使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.

  典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.

  大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。

  当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个, 防止因为不同的类加载器, 导致类型转换异常(ClassCastException).

分享到:
评论

相关推荐

    Java Class Loader总结.doc

    System.out.println("parent class loader: " + cl.getParent()); cl = cl.getParent(); } ``` 这段代码会打印出当前的类加载器以及它们的父加载器。通常,你会看到AppClassLoader(系统类加载器)、...

    class-loader测试工程

    在Java编程语言中,类加载器(Class-Loader)是一个至关重要的组件,它负责加载类到JVM(Java虚拟机)中。这个“class-loader测试工程”可能是一个专门设计用于研究和理解Java类加载机制的项目。在Java中,类加载...

    深入Class Loader

    ### 深入理解Java的Class Loader:动态性与灵活性的核心 #### 一、Class Loader在Java中的核心地位 在Java编程的世界里,类加载器(Class Loader)扮演着极其关键的角色,它不仅支撑起了Java的动态性,还极大地...

    java 类加载器 class loader

    创建自定义类加载器通常需要继承`java.lang.ClassLoader`,重写`findClass()`或`loadClass()`方法,从而控制类的查找和加载过程。这使得开发者能够在运行时根据需要加载特定的类,比如从网络、数据库或其他非传统...

    class_loader_utility.cc

    class_loader_utility.cc

    java class loader(JAVA类加载器)

    1. **类加载器层次结构** Java中的类加载器分为三个主要层次:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(AppClassLoader)。启动类加载器负责加载JRE核心库,...

    class loader

    1. **懒加载**:类只有在被真正需要时才会被加载到内存中。这种策略可以减少不必要的内存占用,并加快系统响应速度。 - **优势**:延迟加载可以显著提高应用程序启动时的速度,因为它避免了一次性加载所有类所...

    IBM WebSphere Application ServerSystem Management – Class Loader

    应用服务器类加载器 共享库 类加载器问题诊断 资源及参考资料

    Ejb class loader

    最后,我们可以参考博客文章《Ejb class loader》(链接:https://sbiigu.iteye.com/blog/323180)来获取更具体的实现细节和技术讨论。该博客可能包含了作者在实际工作中遇到的问题、解决方案以及对EJB类加载器的...

    Classfor的用法

    1. **单参数版本**:`Class.forName(String className)` - 这个方法使用当前线程的上下文类加载器(如果没有设置,则使用系统的应用类加载器)来加载类,并且会初始化该类。 - 代码示例: ```java try { Class...

    C++ Dynamic Class Loader-开源

    在C++编程中,动态类加载(Dynamic Class Loading)是一种高级技术,允许程序在运行时加载未知或在编译时不可用的类。这通常用于实现插件系统、模块化设计或者灵活的软件架构。开源的C++动态类加载机制为开发者提供...

    java class加密保护(完全免费) v2.1

    本工具是对java class文件进行加密保护防止反编译的工具!本工具全面支持linux/unix/windows操作系统。 继推出v1.0版本后,获得了用户大量的支持与的反馈,我们再次推出本v2.0版,对加密算法进行了更大的改进,安全...

    Silverlight Loader

    1.在现有SLLoader.xap项目中使用SilverlightLoader:先下载SilverlightLoader压缩包,从下载的Release中找到SilverlightLoader.cs,并将其添加到SLLoader.xap项目中,具体实现方法:在SLLoader.xap项目中右键添加已...

    loader in java houtian

    1. **加载(Loading)**:这是类加载的第一步,由类加载器完成。加载器根据类名查找对应的.class文件,这个过程可以通过系统类加载器或者自定义的类加载器来实现。一旦找到,字节码会被读取并转化为Class对象。 2. ...

    一个简单的调用sql loader批量数据导入程序

    public class Application1 { public static void main(String[] args) { try { String sqlLoaderCmd = "sqlldr username/password@database control=control_file.ctl log=log_file.log"; Process process = ...

    Android 异步加载显示 Loader 自定义Loader

    1. **创建Loader子类**:你需要继承`android.content.Loader`并实现其抽象方法。例如,可以创建一个名为`CustomImageLoader`的类,继承自`Loader&lt;List&lt;Bitmap&gt;&gt;`。 2. **重写onCreateLoader()**:在这个方法中,...

    Sql Loader 在C#的应用实例

    column1, column2, ... ) ``` 在这个例子中,`N.txt` 是数据文件,每行数据由逗号分隔,字段可以被双引号包围,允许有空值。 接下来,让我们看看如何在 C# 中调用 Sql Loader。`System.Diagnostics.Process` 类...

    java class加密保护工具

    加密算法达到256位,加密后的class文件不可能被破解,反编译工具也对加密后的class文件无能为力。 运行方式: 运行时,要能正确的加载加密后的class文件, 必须使用我们提供的动态链接库classloader.dll(wndows...

    前端开源库-icon-font-loader

    1. **矢量图形支持**:SVG图标可以无损缩放,无论在何种分辨率的设备上都能保持清晰。 2. **文件大小优化**:相比于独立的SVG或图片文件,图标字体可以将所有图标打包成一个字体文件,减少HTTP请求,从而提升页面...

    easyui loader 代码分析

    在上述的Demo1示例中,`easyloader.js`的引入使得页面中的class以"easyui"开头的元素被转化为EasyUI的相应控件。 EasyUI Loader的工作流程大致如下: 1. **初始化**:当`easyloader.js`被引入后,Loader开始初始化...

Global site tag (gtag.js) - Google Analytics