`
hanzhicheng754
  • 浏览: 7971 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

Java 类装载器详解

阅读更多
Java类装载器详解

一:标准JavaSE 类装载器
    1.标准JavaSE 类装载器概述
        本质上来说,类装载器是以某种方式,读取Java类的class文件到JVM中,并将class文件中的信息写入到内存中的一种机制。Java语言中的类装载器可以分为两种:一种是用Java语言编写的(Java程序员只需要关注这种类型的类装载器即可);一种不是用Java语言编写的,我们称之为启动类装载器,它是Java虚拟机实现的一部分。
    2.启动类装载器
        顾名思义,启动类装载器是用于装载JVM启动时需要的Java类。实际上,启动类装载器负责装载所有核心的Java类(例如 java.lang.*和 java.io.*)。启动类装载器以某种特定的方式从本地磁盘(Java虚拟机安装目录)中装载JVM运行所需的Java类。例如如果JVM是用C或者C++编写的,那么JVM的实现者可以调用C或者C++的API来装载Java class文件到JVM中。有些人知道了启动类装载器装载了核心的Java类,他们可能还想知道,启动类状态器具体在哪里找到这些类。JAR文件的查找方法因厂商的不同而变化。例如Sun的Java SE 5 JVM在<JDK>/jre/lib目录下查找JAR文件,尤其在<JDK>/jre/lib/rt.jar目录下查找启动类。对于Sun的JVM,可以使用 -Xbootclasspath 为JVM查找启动类的位置,一般而言,我们不需要这么做。
(启动类装载器在一个JVM实现中,只有一个。也有翻译成引导类装载器,原始类装载器的,但我觉得启动类装载器最为精确)
    3.扩展类装载器
        Java 1.2 引入了标准扩展机制。通常情况下,当我们想让JVM在某个特定的位置查找类文件时,我们会更改CLASSPATH环境变量,将类文件加入到CLASSPATH环境变量中。(或者使用 -classpath 选项)。Sun引入了标准扩展机制作为一个可选的方法,可以将JAR文件放入到标准扩展目录,JVM将自动找到他们。
       一般情况下,扩展类装载器是用Java语言编写的。标准扩展目录也会随着JVM厂商的不同而不同,Sun的JVM的标准扩展目录为<JDK>/jre/lib/ext。
    4.系统类装载器
        系统类装载器是Java 1.2引入的系统默认Java实现,当然,它是用Java编写的。系统类装载器在目录和CLASSPATH环境变量指定的JAR文件中查找自己的类,或者通过-classpath命令行选项传递的类。系统类装载器也用于装载应用程序的entry point类(即含有main()方法的类),对于那些其他任何没有上述的两类类装载器装载的类,都默认使用系统类装载器。
(系统类装载器有时被称为应用程序类装载器,虽然更为贴切,不过系统类装载器是Sun的约定)
二:委派模型
     
      如前所述,Java SE用于3种不同的类装载器。他们之间的关系可以用父子关系形容。启动类装载器是爷爷,系统类装载器是孙子,优先级最低。JDK1.2以后的JVM版本都会使用委派模型。当JVM受到装载类的请求时,只有在父类装载器未能装载该类的情况下,原始类(子类)才会尝试装载该类。举个例子来说,你定义了一个类名为A的类。当你请求装载该类时,系统类装载器会受到请求(为什么是系统类装载器会先收到请求?),他首先想到的不是自己去装载这个类,而是会想,难不成他在扩展类装载器那?于是乎他就找到扩展类装载器,问他类A在你那吗?扩展类装载器收到请求后第一件事情也不是做事,而是在想,难不成他在启动类装载器那?于是乎,他又找到了启动类装载器,问他了,喂看看类A在你那不?当然了,启动类装载器在接到请求后,第一件想到的事情也不是自己去装载类A啊,他也想问他老子啊,可他一看,他前面没人了啊 。于是乎,没办法,他就到自己的装载域中找找看有没有类A。找了半天,他没发现类A,他就告诉扩展类装载器,跟他说,我这没有啊 ,你自己找找看吧,扩展类装载器就去自己的装载域中找了,结果没发现,于是,他也只能不好意思的跟系统类装载器说,我这也没有啊 ,还是你自己来吧。于是,系统类装载器就自己去找了,他当然能找到啦,于是就把对象的引用返回了。(写了这么久的Java程序了,有没有弄清楚,JVM在什么时候装载一个类?)
三:Endorsed Standards Override 机制
    Java 1.4引入了称为 Endorsed Standards Override 机制的概念,在Java SE1.5中也可以使用该机制。随着时间的推移,核心的Java SE发布已经包括越来越多的Java扩展(曾经认为是可选的)。其中一个很好的例子就是J2SE 1.4包含XML处理的Java API(JAXP)。既包括JAXP的API类,也包括其实现。实现类包含在rt.jar中,启动类装载器将装载它们。因此,如果程序员将更新版本的JAXP实现与该JDK一起放到CLASSPATH中,新的版本将不能使用。
四:Java 类装载器在安全模型中扮演的角色
    在计算机的世界里,以说到安全问题,我们可就又回到了严肃而认真的问题上了。显然,类装载器体系位于Java安全模型的中心。(为什么?)是否还记得我们上述的三种类装载器,其中最重要的就是启动类装载器装载的类了,如果一个第三者的java.lang.String 插足到JVM中了,他成了你调用的String 类,结果他把你的硬盘给格了,你是否会崩溃?
   1.委派模型
    前述的委派模型通常被描述为一个安全特性。你看了之后是不是也觉得是那么回事呢?
启动类装载器装载了所有的JVM自带的核心Java API。任何装载核心的Java类的请求,都会在启动类装载器那获得它所保存的副本。
    但是,委派模型并不是JVM规范的一部分,所以委派模型在安全方面是存在缺陷的。(乖乖,又想到一个问题,为什么不把他加入到JVM规范中呢?那样Java岂不是更安全?)
   2.我们不是可以自定义类装载器吗?你要是不把请求委派给父类装载器,你怎么阻止别人装载java.lang.String呢?事实上任何用Java语言编写的类装载器,都不能装载核心的Java类。ClassLoader抽象类(所有类装载器必须继承的)禁止创建任何以java开始的类。你的类装载器还能装载核心的java类吗?不能吧?那还是让启动类装载器来干吧。
   4.第二条所述的只是在装载类的时候,限制了错误的核心类被装载,那么在运行时,怎么保证JVM的安全呢?Sun的策略有两种,第一就是独立的类装载器命名空间。
     JVM在运行时,会为每个类监视每个运行的类装载器,并为之分配一个唯一的命名空间。并且,当JVM在运行Java代码时,收到一个类发出装载另一个类的请求时,他会先找到装载发出请求的类的装载器,并用他来装载待装载的类。这样的话,不同的类装载器装载的类就会有不同的命名空间。同一个类装载器装载的类之间可以进行直接交换,不同的类装载器装载的类之间不可以进行直接交换,JVM会禁止这样的行为,除非你的程序显式的允许。大家都知道,在Java语言中,我们区分不同的类,是通过包名加类名(完全限定名),实际在JVM中,还会在你的类之前加上类装载器的命名空间。也就是说,两个不同的类装载器均装载了com.Test.java这个Java类,在JVM看来,会认为他们不是同一个类。这样的话,在运行状态下,恶意的代码就不能够破话善意的代码了。
   5.Security Manager
     如果真的想保证自定义类装载器不能破坏程序,可以在应用程序中完全阻止它。这可以通过Security Manager类完成。
    使用Security Manager和它的策略文件,可以在应用程序中阻止(或者不阻止)大量的任务。例如,可以阻止应用程序打开和某个网络主机的socket连接,或者打开某个本地文件。此外,还可以阻止应用程序装载类装载器。
    至于怎么使用Security Manager则又是另外一个话题了。
四:类装载器的其他行为
    1.延迟加载
    2.类缓存
   
五:为什么我们要学习类装载器
    这个问题问的真是好,我说了那么多废话,只是让我们学习了之后去写属于我们自己的类装载器吗?当然不是,很少情况下,我们需要写。
     那么,学习类装载器干什么?我们不知道他,还不是照样可以编程,照样做Java程序员,事实上,我也经常问自己这些问题
     由于本人Java的从业时间不长,知道的不多。
     目前来看,主要有:
     1.深入Java虚拟机的学习有帮助
     2.我在学习Tomcat时,也有很多帮助。比如Tomcat中不同的Context。
    
分享到:
评论
1 楼 medicine 2012-09-13  
l

相关推荐

    jvm类装载器原理

    《JVM类装载器原理详解》 Java的JVM(Java Virtual Machine)类装载器是Java运行时系统的重要组成部分,负责在程序运行期间查找并加载类的二进制数据。理解类装载器的工作原理对于优化Java应用性能和实现动态加载类...

    java类加载过程详解.doc

    Java 类加载过程是Java虚拟机(JVM)在运行时动态加载类的机制,它涉及类的生命周期中的几个关键步骤,包括装载、连接、初始化和卸载。下面将详细阐述这些过程。 1. 装载 装载阶段是类加载的起始点,主要分为三个...

    Java四大核心技术思想详解.doc

    Java类装载器体系结构设计灵活,支持不同类型的类装载器来适应不同的应用场景。主要分类包括: 1. **启动类装载器(Bootstrap Class Loader)**:它是JVM的一部分,负责加载Java核心库,如`rt.jar`。这些库通常位于...

    Java2语言命令详解

    `jstat`用于收集JVM的运行时统计信息,包括垃圾收集、类装载、编译器等。例如,`jstat -gc &lt;pid&gt; 1000 5`会每秒收集一次GC信息,共收集5次。 10. **jinfo**:配置信息工具 `jinfo`用于查看和修改JVM的配置信息,...

    Java的四大核心技术

    每个Java应用程序都有一个初始类装载器(Bootstrap ClassLoader),它是所有其他类装载器的父装载器。 - **双亲委派模型**:类装载器遵循一种称为“双亲委派模型”的原则,即子类装载器会先委托其父类装载器尝试...

    深入讲解Java虚拟机系列之方法区

    * 装载该类的类装载器引用:存储类装载器的引用信息。 * java.lang.Class 类对象的引用:当装载一个 class 文件时,会创建一个 java.lang.Class 的对象,该对象就代表了这个类型。 2. 方法区的概念图 通过方法区的...

    java虚拟机详解.docx

    ### Java虚拟机(JVM)详解 #### 一、Java技术概览 Java不仅仅是一种编程语言,更是一项由多个组成部分构成的技术。这些组成部分包括Java编程语言、Java类文件格式、Java虚拟机(JVM)以及Java应用程序接口(API)。它们...

    java虚拟机详解免费.pdf

    类装载子系统负责加载Java程序需要的类文件,是整个JVM工作的第一步。它通过类加载器加载字节码文件,然后进行链接、验证、准备、解析和初始化等步骤,最终将类信息加载到JVM内存中。 内存区域方面,JVM将内存划分...

    JAVA学习笔记详解

    字节码在执行前会经过类装载器和字节码验证器的检查,以防止非法操作。对于 applet 程序而言,其访问权限被严格限制,无法直接访问本地文件系统。 4. **Java语言的特点** - Java 与 C/C++ 相比有几个显著特点: -...

    Java-Jdbc技术详解(ppt文档).ppt

    Java-Jdbc技术详解 Java-Jdbc技术是Java程序连接和存取数据库的应用程序接口(API),该接口是Java核心API的一部分。JDBC向应用程序开发者提供了独立于数据库的统一的API。JDBC是由一组驱动程序实现的Java接口,...

    大学课程讲义-Java基础-反射.pptx

    ClassLoader类是Java中的类装载器,负责把类(class)装载进JVM。JVM规范定义了两种类型的类装载器:启动类装载器(bootstrap)和用户自定义装载器(user-defined class loader)。JVM在运行时会产生3个类加载器组成的初始...

    JBoss管理与开发

    Java中的类装载器是一种特殊的类,负责加载Java类和资源到JVM中。每个类装载器都有一个父类装载器,形成了一个层次结构。Java中存在三种基本类型的类装载器: - **Bootstrap Class Loader**:这是JVM自带的类装载器...

    Java中的四个核心技术

    - **启动类装载器(Bootstrap ClassLoader)**:这是最顶层的类装载器,负责加载JVM核心类库,如`java.lang.*`等包中的类。 - **扩展类装载器(Extension ClassLoader)**:这个类装载器负责加载扩展目录下的jar包。...

    Java软件开发实战 Java基础与案例开发详解 2-5 java虚拟机简介 共8页.pdf

    1. **类装载器(Class Loader)**:负责读取并加载Java类文件到JVM中。 2. **字节码校验器(Bytecode Verifier)**:确保加载到JVM中的字节码是安全的,不会破坏系统的稳定性和安全性。 3. **解释器(Interpreter)**:...

Global site tag (gtag.js) - Google Analytics