- 浏览: 485311 次
- 性别:
- 来自: 长沙
文章分类
最新评论
-
Source_野驴:
...
jsp静态化和伪静态化 -
zidanzzg:
很好的知识,找到了利用异或交换数值的理论支持,谢谢分享
XOR的性质和运算 -
ueseu:
引用(2) DomainDomain域名也是Cookie的一部 ...
Cookie的组成 -
ueseu:
引用Secure取true或者false值。如果为true,那 ...
Cookie的组成 -
liqi___123:
理解得很透彻,谢谢!!
ROLAP、MOLAP和HOLAP联机分析处理区别
再次阅读这篇文章时,有了更深的体会,特转载之。
理解Java ClassLoader机制
当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构:
bootstrap classloader -引导(也称为原始)类加载器,它负责加载Java的核心类。在Sun的JVM中,在执行java的命令中使用-Xbootclasspath选项或使用 - D选项指定sun.boot.class.path系统属性值可以指定附加的类。这个加载器的是非常特殊的,它实际上不是 java.lang.ClassLoader的子类,而是由JVM自身实现的。大家可以通过执行以下代码来获得bootstrap classloader加载了那些核心类库:
extension classloader -扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中JAR的 类包。这为引入除Java核心类以外的新功能提供了一个标准机制。因为默认的扩展目录对所有从同一个JRE中启动的JVM都是通用的,所以放入这个目录的 JAR类包对所有的JVM和system classloader都是可见的。在这个实例上调用方法getParent()总是返回空值null,因为引导加载器bootstrap classloader不是一个真正的ClassLoader实例。所以当大家执行以下代码时:
System.out.println(System.getProperty("java.ext.dirs"));
ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
结果为:
C:\j2sdk1.4.1_01\jre\lib\ext
the parent of extension classloader : null
extension classloader是system classloader的parent,而bootstrap classloader是extension classloader的parent,但它不是一个实际的classloader,所以为null。
system classloader -系统(也称为应用)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或 者 CLASSPATH操作系统属性所指定的JAR类包和类路径。总能通过静态方法ClassLoader.getSystemClassLoader()找 到该类加载器。如果没有特别指定,则用户自定义的任何类加载器都将该类加载器作为它的父加载器。执行以下代码即可获得:
System.out.println(System.getProperty("java.class.path"));
输出结果则为用户在系统属性里面设置的CLASSPATH。
classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入;委托机制则是先让parent(父)类加载器 (而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。此外类加载还采用了cache机制,也就是如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么我们修改了Class但是必 须重新启动JVM才能生效的原因。
类加载器的顺序是:
先是bootstrap classloader,然后是extension classloader,最后才是system classloader。大家会发现加载的Class越是重要的越在靠前面。这样做的原因是出于安全性的考虑,试想如果system classloader“亲自”加载了一个具有破坏性的“java.lang.System”类的后果吧。这种委托机制保证了用户即使具有一个这样的类, 也把它加入到了类路径中,但是它永远不会被载入,因为这个类总是由bootstrap classloader来加载的。大家可以执行一下以下的代码:
System.out.println(System.class.getClassLoader());
将会看到结果是null,这就表明java.lang.System是由bootstrap classloader加载的,因为bootstrap classloader不是一个真正的ClassLoader实例,而是由JVM实现的,正如前面已经说过的。
下面就让我们来看看JVM是如何来为我们来建立类加载器的结构的:
sun.misc.Launcher,顾名思义,当你执行java命令的时候,JVM会先使用bootstrap classloader载入并初始化一个Launcher,执行下来代码:
System.out.println("the Launcher's classloader is "+sun.misc.Launcher.getLauncher().getClass().getClassLoader());
结果为:
the Launcher's classloader is null (因为是用bootstrap classloader加载,所以class loader为null)
Launcher 会根据系统和命令设定初始化好class loader结构,JVM就用它来获得extension classloader和system classloader,并载入所有的需要载入的Class,最后执行java命令指定的带有静态的main方法的Class。extension classloader实际上是sun.misc.Launcher$ExtClassLoader类的一个实例,system classloader实际上是sun.misc.Launcher$AppClassLoader类的一个实例。并且都是 java.net.URLClassLoader的子类。
让我们来看看Launcher初试化的过程的部分代码。
Launcher的部分代码:
extension classloader的部分代码:
system classloader的部分代码:
bootstrap classloader | extension classloader | system classloader
bootstrap classloader -引导(也称为原始)类加载器,它负责加载Java的核心类。在Sun的JVM中,在执行java的命令中使用-Xbootclasspath选项或使用 - D选项指定sun.boot.class.path系统属性值可以指定附加的类。这个加载器的是非常特殊的,它实际上不是 java.lang.ClassLoader的子类,而是由JVM自身实现的。大家可以通过执行以下代码来获得bootstrap classloader加载了那些核心类库:
1 |
URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs(); |
2 |
for ( int i = 0 ; i < urls.length; i++) {
|
3 |
System.out.println(urls.toExternalform());
|
4 |
}
|
extension classloader -扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中JAR的 类包。这为引入除Java核心类以外的新功能提供了一个标准机制。因为默认的扩展目录对所有从同一个JRE中启动的JVM都是通用的,所以放入这个目录的 JAR类包对所有的JVM和system classloader都是可见的。在这个实例上调用方法getParent()总是返回空值null,因为引导加载器bootstrap classloader不是一个真正的ClassLoader实例。所以当大家执行以下代码时:
System.out.println(System.getProperty("java.ext.dirs"));
ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
结果为:
C:\j2sdk1.4.1_01\jre\lib\ext
the parent of extension classloader : null
extension classloader是system classloader的parent,而bootstrap classloader是extension classloader的parent,但它不是一个实际的classloader,所以为null。
system classloader -系统(也称为应用)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或 者 CLASSPATH操作系统属性所指定的JAR类包和类路径。总能通过静态方法ClassLoader.getSystemClassLoader()找 到该类加载器。如果没有特别指定,则用户自定义的任何类加载器都将该类加载器作为它的父加载器。执行以下代码即可获得:
System.out.println(System.getProperty("java.class.path"));
输出结果则为用户在系统属性里面设置的CLASSPATH。
classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入;委托机制则是先让parent(父)类加载器 (而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。此外类加载还采用了cache机制,也就是如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么我们修改了Class但是必 须重新启动JVM才能生效的原因。
类加载器的顺序是:
先是bootstrap classloader,然后是extension classloader,最后才是system classloader。大家会发现加载的Class越是重要的越在靠前面。这样做的原因是出于安全性的考虑,试想如果system classloader“亲自”加载了一个具有破坏性的“java.lang.System”类的后果吧。这种委托机制保证了用户即使具有一个这样的类, 也把它加入到了类路径中,但是它永远不会被载入,因为这个类总是由bootstrap classloader来加载的。大家可以执行一下以下的代码:
System.out.println(System.class.getClassLoader());
将会看到结果是null,这就表明java.lang.System是由bootstrap classloader加载的,因为bootstrap classloader不是一个真正的ClassLoader实例,而是由JVM实现的,正如前面已经说过的。
下面就让我们来看看JVM是如何来为我们来建立类加载器的结构的:
sun.misc.Launcher,顾名思义,当你执行java命令的时候,JVM会先使用bootstrap classloader载入并初始化一个Launcher,执行下来代码:
System.out.println("the Launcher's classloader is "+sun.misc.Launcher.getLauncher().getClass().getClassLoader());
结果为:
the Launcher's classloader is null (因为是用bootstrap classloader加载,所以class loader为null)
Launcher 会根据系统和命令设定初始化好class loader结构,JVM就用它来获得extension classloader和system classloader,并载入所有的需要载入的Class,最后执行java命令指定的带有静态的main方法的Class。extension classloader实际上是sun.misc.Launcher$ExtClassLoader类的一个实例,system classloader实际上是sun.misc.Launcher$AppClassLoader类的一个实例。并且都是 java.net.URLClassLoader的子类。
让我们来看看Launcher初试化的过程的部分代码。
Launcher的部分代码:
01 |
public class Launcher {
|
02 |
public Launcher() {
|
03 |
ExtClassLoader extclassloader;
|
04 |
try {
|
05 |
//初始化extension classloader
|
06 |
extclassloader = ExtClassLoader.getExtClassLoader();
|
07 |
} catch (IOException ioexception) {
|
08 |
throw new InternalError( "Could not create extension class loader" );
|
09 |
}
|
10 |
try {
|
11 |
//初始化system classloader,parent是extension classloader
|
12 |
loader = AppClassLoader.getAppClassLoader(extclassloader);
|
13 |
} catch (IOException ioexception1) {
|
14 |
throw new InternalError( "Could not create application class loader" );
|
15 |
}
|
16 |
//将system classloader设置成当前线程的context classloader(将在后面加以介绍)
|
17 |
Thread.currentThread().setContextClassLoader(loader); |
18 |
......
|
19 |
}
|
20 |
public ClassLoader getClassLoader() {
|
21 |
//返回system classloader
|
22 |
return loader;
|
23 |
}
|
24 |
}
|
extension classloader的部分代码:
01 |
static class Launcher$ExtClassLoader extends URLClassLoader {
|
02 |
|
03 |
public static Launcher$ExtClassLoader getExtClassLoader()
|
04 |
throws IOException
|
05 |
{
|
06 |
File afile[] = getExtDirs();
|
07 |
return (Launcher$ExtClassLoader)AccessController.doPrivileged( new Launcher$ 1 (afile));
|
08 |
}
|
09 |
private static File[] getExtDirs() {
|
10 |
//获得系统属性“java.ext.dirs”
|
11 |
String s = System.getProperty( "java.ext.dirs" );
|
12 |
File afile[];
|
13 |
if (s != null ) {
|
14 |
StringTokenizer stringtokenizer = new StringTokenizer(s, File.pathSeparator);
|
15 |
int i = stringtokenizer.countTokens();
|
16 |
afile = new File;
|
17 |
for ( int j = 0 ; j < i; j++)
|
18 |
afile[j] = new File(stringtokenizer.nextToken());
|
19 |
|
20 |
} else {
|
21 |
afile = new File[ 0 ];
|
22 |
}
|
23 |
return afile;
|
24 |
}
|
25 |
}
|
system classloader的部分代码:
01 |
static class Launcher$AppClassLoader extends URLClassLoader
|
02 |
{
|
03 |
|
04 |
public static ClassLoader getAppClassLoader(ClassLoader classloader)
|
05 |
throws IOException
|
06 |
{
|
07 |
//获得系统属性“java.class.path”
|
08 |
String s = System.getProperty( "java.class.path" );
|
09 |
File afile[] = s != null ? Launcher.access$ 200 (s) : new File[ 0 ];
|
10 |
return (Launcher$AppClassLoader)AccessController.doPrivileged( new Launcher$ 2 (s, afile, classloader));
|
11 |
}
|
12 |
}
|
发表评论
-
java String.getBytes()编码问题 (讲到实处了)
2012-12-12 11:26 796转载自: String.getBytes()的问 ... -
JSP中文验证码
2012-05-14 17:18 1245以上两篇文章的内容介绍了有关JSP中产生数字验证码跟中文验证 ... -
One-Jar之旅
2011-09-16 10:06 1766One-Jar之旅 1 ... -
Javamail中的常见中文乱码问题与解决办法
2011-09-09 09:48 1657在使用javamail api开发邮件服务系统时,我们常常会碰 ... -
JAVA泛型简介
2011-07-22 13:41 1235另篇:http://www.java3z.com/cwbweb ... -
BCEL和Javassist的介绍
2011-07-18 10:49 1608BCEL 介绍: Byte Code E ... -
类加载器特技:OSGi代码生成
2011-07-18 10:08 801转自:http://www.oschina.n ... -
开源的java编译器jikes
2011-06-19 08:50 2248今天才知道java编译器还有个jikes这样的开源产品。 ... -
java的沙盒机制
2011-01-28 18:03 2047JAVA 的安全模型不同于传统的安全方法,传统的安全方法中 ... -
filter的调用顺序
2011-01-06 11:54 1290在一个大型项目中往往有多个servlet过滤器,但是这些ser ... -
JAVA操作COOKIE
2010-12-28 11:32 12751.设置Cookie Cookie cookie = ... -
监视器和锁
2010-12-17 16:54 1784http://topic.csdn.net/t/20050 ... -
关于volatile变量的理解
2010-12-12 13:21 1004前些日子在看些多线 ... -
关于Java 构造函数和继续特性的回顾
2010-12-06 09:21 1202java构造函数 java类库的设计者们通过提供 ... -
Java可变参数方法重载的错误3例
2010-12-05 23:28 1123JDK1.5引进了方法的可变参数,受到许多开发人员的青睐。 ... -
JDK1.5新特性
2010-12-05 23:19 721"JDK1.5"的一个重要主题就是 ... -
序列化中serialVersionUID的使用
2010-12-04 08:39 1369先来看一个例子: 定义一个bean: Java代码 ... -
Java 语言的 XPath API
2010-12-02 15:31 959如果要告诉别人买一加仑牛奶,您会怎么说?“请去买一加仑牛 ... -
java -verbose命令
2010-09-23 15:00 9399java -verbose[:class|gc|jni ... -
db2的jdbc驱动
2010-09-20 18:34 1276type1:jdbc-odbc桥 ...
相关推荐
Java ClassLoader机制是Java虚拟机(JVM)中一个至关重要的组成部分,它的主要任务是将类的.class文件加载到JVM中,使得程序能够运行。ClassLoader不仅负责类的加载,还涉及类的验证、初始化等一系列过程。理解...
理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将深入探讨Java ClassLoader的内部工作,并通过一个具体的实例来展示如何定制自己的ClassLoader。 ...
深入Java 2 SDK.pdf`可能涉及的是Java与其他工具和技术的集成,如与微软Office的交互、使用Visual Studio .NET管理Java应用、Ant构建工具的使用以及对Java 2 SDK的深入理解,这些都可能间接地涉及到ClassLoader的...
本文主要围绕Java类加载器和类路径展开讨论,以加深对Java运行时类加载机制的理解。 #### 二、ClassLoader详解 ##### 2.1 类加载器的概念 类加载器(`ClassLoader`)是Java运行时环境的一部分,它的主要职责是从...
Java Classloader 机制用法代码解析 Java Classloader 机制用法代码解析是 Java 编程语言中的一种机制,负责加载 Java 类...了解 Java Classloader 机制可以帮助我们更好地理解 Java 编程语言并编写高效的 Java 程序。
### Java ClassLoader原理详解 #### 摘要 本文探讨了Java虚拟机(JVM)中的一个重要特性:动态类加载(Dynamic Class Loading)。...了解和掌握这些概念对于深入理解和高效利用Java平台至关重要。
了解 Java 类加载机制可以帮助我们更好地理解 Java 的运行机制,并且可以帮助我们更好地编写 Java 程序。 知识点总结: * Java 类加载机制是 Java 中一个非常重要的机制,它负责加载 Class 文件到 JVM,以供程序...
《深入理解ClassLoader工作机制》 Java虚拟机(JVM)中的ClassLoader是负责加载类到内存中的核心组件。它不仅承担着将字节码转换为可执行对象的重任,还参与了类生命周期的各个阶段,包括加载、验证、准备、解析、...
通过本教程的学习,你将能够理解Java ClassLoader的基本概念及其工作原理,并学会如何创建自定义的ClassLoader。自定义ClassLoader不仅能够扩展JVM的功能,还能够在实际项目中解决特定问题,如动态加载远程资源、...
理解ClassLoader的工作机制对于深入掌握Java应用程序的运行至关重要。这里我们将详细讨论ClassLoader的运行机制,特别是自定义ClassLoader的设计与实现。 ClassLoader的基本职责是根据类名动态加载对应的类文件。在...
总结,Java ClassLoader是Java平台的关键特性,理解其工作原理和应用场景对于优化系统性能、设计可扩展的系统至关重要。通过本教程,读者应能掌握如何利用ClassLoader实现动态加载、安全隔离和版本控制等功能,提升...
通过对Java ClassLoader的深入了解,我们可以更好地理解Java类的加载机制以及如何通过自定义ClassLoader来满足特定的应用需求。淘宝网的成功实践为我们提供了宝贵的参考案例,展示了ClassLoaders在实际项目中的重要...
总的来说,深入理解Java的ClassLoader机制对于优化应用程序性能、实现动态加载、理解和解决类加载问题都至关重要。它为Java提供了灵活性和可扩展性,是Java平台的一个强大特性。通过掌握ClassLoader的工作原理,...
Java 类加载器(ClassLoader)是Java虚拟机(JVM)中的一个重要组成部分,它负责加载类的字节码文件,使得程序能够运行。深入理解ClassLoader对于优化应用性能、处理类加载问题以及实现自定义加载策略至关重要。 一...
《深入理解Java类加载器:基于classloader-playground开源项目》 在Java世界里,类加载器(ClassLoader)是理解JVM工作原理的关键一环。它负责将字节码文件(.class)从磁盘、网络或其他数据源加载到内存,并转化为...