`
zha_zi
  • 浏览: 586618 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

jvm系列 ClassLoader原理

 
阅读更多

                 ClassLoader原理

JVM规范定义了两种类型的类装载器:启动内装载器 (bootstrap) 和用户自定义装载器 (user-defined class loader)

一.    ClassLoader 基本概念
1 ClassLoader 分类
类装载器是用来把类(class)装载进JVM的。
JVM规范定义了两种类型的类装载器:启动内装载器 (bootstrap) 和用户自定义装载器 (user-defined class loader)


JVM在运行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader. Bootstrap是用C++编写的,我们在Java中看不到它,是null,是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。
AppClassLoader Parent ExtClassLoader ,而 ExtClassLoader Parent Bootstrap ClassLoader
 
Java 提供了抽象类 ClassLoader ,所有用户自定义类装载器都实例化自 ClassLoader 的子类。 System Class Loader 是一个特殊的用户自定义类装载器,由 JVM 的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类 。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
 
例1,测试你所使用的JVM的ClassLoader

public   class  LoaderSample1 {
     public   static   void  main(String[] args) {
        Class c;
        ClassLoader cl;
        cl  =  ClassLoader.getSystemClassLoader();
        System.out.println(cl);
         while  (cl  !=   null ) {
            cl  =  cl.getParent();
            System.out.println(cl);
        }
         try  {
            c  =  Class.forName( " java.lang.Object " );
            cl  =  c.getClassLoader();
            System.out.println( " java.lang.Object's loader is  "   +  cl);
            c  =  Class.forName( " LoaderSample1 " );
            cl  =  c.getClassLoader();
            System.out.println( " LoaderSample1's loader is  "   +  cl);
        }  catch  (Exception e) {
            e.printStackTrace();
        }
    }
} 

 sun.misc.Launcher$AppClassLoader@1a0c10f
sun.misc.Launcher$ExtClassLoader@e2eec8
null
java.lang.Object's loader is null
LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@1a0c10f

第一行表示,系统类装载器实例化自类sun.misc.Launcher$AppClassLoader
第二行表示,系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
第三行表示,系统类装载器parent的parent为bootstrap
第四行表示,核心类java.lang.Object是由bootstrap装载的
第五行表示,用户类LoaderSample1是由系统类装载器装载的

 

 

二. parent delegation模型
从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的 parent 去装载,若 parent 能装载,则返回这个类所对应的 Class 对象,若 parent 不能装载,则由 parent 的请求者去装载

图 1 parent delegation模型
如 图1所示,loader2的parent为loader1,loader1的parent为system class loader。假设loader2被要求装载类MyClass,在parent delegation模型下,loader2首先请求loader1代为装载,loader1再请求系统类装载器去装载MyClass。若系统装载器能成 功装载,则将MyClass所对应的Class对象的reference返回给loader1,loader1再将reference返回给 loader2,从而成功将类MyClass装载进虚拟机。若系统类装载器不能装载MyClass,loader1会尝试装载MyClass,若 loader1也不能成功装载,loader2会尝试装载。若所有的parent及loader2本身都不能装载,则装载失败。
 
若有一 个能成功装载,实际装载的类装载器被称为定义类装载器,所有能成功返回Class对象的装载器(包括定义类装载器)被称为初始类装载器。如图1所示,假设 loader1实际装载了MyClass,则loader1为MyClass的定义类装载器,loader2和loader1为MyClass的初始类装 载器。
 
需要指出的是,Class Loader是对象,它的父子关系和类的父子关系没有任何关系。
 
那么parent delegation模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类,从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码。实际上,类装载器的编写者可以自由选择不用把请求委托给 parent ,但正如上所说,会带来安全的问题。

 

类加载器主要分三种:bootstrap(由C语言编写,固化在jvm上)、ExtClassLoader、AppClassLoader。
而bootstrao主要加载rt.jar,ExtClassLoader主要加载Jdk安装路径/jre/lib/ext下的字节码,
AppClassLoader主要加载ClassPath下的字节码,类加载器的委托加载原理,
首先加载类一直交给父类加载器加载,一直提交到bootstrap,
当父类加载器加载不到时,在一层层的返回给下一级加载器加载

 

三.命名空间及其作用
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
 
例 2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装 载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的 reference,所以它可以访问LoaderSampl3中公共的成员(如age)。
例2不同命名空间的类的访问

mport  java.net. * ;
import  java.lang.reflect. * ;
public   class  LoaderSample2 {
     public   static   void  main(String[] args) {
         try  {
            String path  =  System.getProperty( " user.dir " );
            URL[] us  =  { new  URL( " file:// "   +  path  +   " /sub/ " )};
            ClassLoader loader  =   new  URLClassLoader(us);
            Class c  =  loader.loadClass( " LoaderSample3 " );
            Object o  =  c.newInstance();
            Field f  =  c.getField( " age " );
             int  age  =  f.getInt(o);
            System.out.println( " age is  "   +  age);
        }  catch  (Exception e) {
            e.printStackTrace();
        }
    }
}
 
public   class  LoaderSample3 {
     static  {
        System.out.println( " LoaderSample3 loaded " );
    }
     public   int  age  =   30 ;
} 

 编译:javac LoaderSample2.java; javac sub/LoaderSample3.java
运行:java LoaderSample2
LoaderSample3 loaded
age is 30
从运行结果中可以看出,在类LoaderSample2中可以创建处于另一命名空间的类LoaderSample3中的对象并可以访问其公共成员age。
运行时包(runtime package)
由 同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相 同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自 己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装 载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。

加载原则

加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入


总结
命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了 Java 的安全,运行时包增加了对包可见成员的保护。

 

 

 

 

分享到:
评论

相关推荐

    深入JVM内核 - 原理、诊断与优化

    在本课程中个,将详细介绍JVM的基本原理、组成以及工作方式,并配合实际案例,介绍相关的调优技巧。 课程大纲: 第一课 初识JVM JVM分类 Java语言规范 JVM规范 介绍JVM的基本知识和发展历史,并介绍了Java语言...

    JVM类加载机制详细讲解

    讲解JVM的ClassLoader子系统原理.

    06.JVM原理讲解和调优.pdf

    JVM 原理讲解和调优 JVM(Java Virtual Machine,Java 虚拟机)是 Java 语言的核心组件,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM 的主要功能是将 Java 字节码转换为...

    JVM原理-jvm内存及相关图示

    JVM原理-jvm内存及相关图示 JVM(Java Virtual Machine)是Java开发工具包(JDK)的一部分,它的主要作用是将Java字节码文件(.class文件)解释并执行,使得Java语言可以跨平台运行。JVM主要由类加载子系统、执行...

    【图解版】深入分析ClassLoader类加载工作机制

    【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!

    jvm笔记

    JVM 笔记 今天,我们要讨论的是 JVM 的笔记,这个笔记包括了 JVM 的基本结构、类加载机制、类文件...在学习 JVM 的过程中,我们需要掌握这些知识点,并且需要了解 JVM 的内部机制,以便更好地理解 JVM 的工作原理。

    JVM-HotSpot-原理

    • HotSpot • ClassFile • ClassLoader • 内存模型、锁、同步 • JVM内存管理和垃圾收集 Java发展历程 JVM列表 OpenJDK 编译执行过程 解析执行和JIT编译

    ClassLoader 详解.doc

    关于J2EE服务器的ClassLoader的原理,该文档清晰了揭示了jvm装载类的顺序,同时用户可以自定义修改classLoader的配置 通过该文档,可以加深对Java虚拟机的理解

    ClassLoader加载机制

    该电子书详细介绍了java虚拟机类加载机制,对于深入理解jvm工作原理有很好的帮助作用,对于初学java,有一定工作经验的小伙伴来说是一本提高自身java素养,夯实自己java基本技能的“葵花宝典”。

    JVM加载class文件的原理机制.pdf

    JVM加载class文件的原理机制 JVM加载class文件的原理机制是Java虚拟机中一个非常重要的组件,负责将class文件加载到内存中,以便Java程序的执行。下面是JVM加载class文件的原理机制的详细介绍: 类加载的原理 在...

    JVM基础教程

    有关JVM的基础教程。介绍JVM原理:hotspot、classfile、classloader、内存模型、锁、同步、JVM内存管理和垃圾收集。

    codeegginterviewgroup#CodeEggDailyInterview#84.JVM加载class文件的原理机制

    JVM加载class文件的原理机制JVM加载class文件的原理机制 JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加

    JVM中编译Class、内存回收、多线程原理和使用

    class文件通常由类加载器(ClassLoader)来完成加载;class的执行在Sun JDK中有解释执行和编译为机器码执行两种方式,其中编译为机器码又分为client和server两种模式。Sun JDK为了提升class的执行效率,对于解释执行...

    Arthas开源的Java诊断工具.rar

    Arthas 的基本原理是使用 Java Agent 实现的,它会在应用程序启动时向 JVM 中注入一个 Java Agent,该 Agent 可以修改字节码,动态地为应用程序增加一些代码。通过这种方式,Arthas 可以在应用程序运行时,动态地...

    Java编程语言的基本原理.docx

    在运行阶段,java.exe 命令会启动 JVM,JVM 会启动类加载器 ClassLoader。ClassLoader 会去硬盘上搜索.class 文件,找到该文件则将该字节码文件装载到 JVM 中。然后,JVM 将字节码文件解释成二进制数据,并与操作...

    Java虚拟机工作原理详解

    * User-Defined Class Loader:这是开发人员通过拓展 ClassLoader 类定义的自定义加载器,加载程序员定义的一些类。 类加载器之间存在一种委派模式(Delegation Mode),当 JVM 加载一个类的时候,下层的加载器会将...

    Java虚拟机类装载:原理、实现与应用

    类的动态装载机制是JVM的一...本文介绍了JVM中类装载的原理、实现以及应用,尤其分析了ClassLoader的结构、用途以及如何利用自定义 的ClassLoader装载并执行Java类,希望能使读者对JVM中的类装载有一个比较深入的理解。

    摩根面试宝典-JVM,GC,Spring etc.

    包含了摩根面试的技术要点,涉及JVM架构,内存回收,Classloader等JDK底层技术,也包括像HashMap,ConcurrentHashMap,Object线程同步等API的解读,还涉及了Spring AOP原理解析等框架技术。

    JVM——Java虚拟机架构

    JVM=类加载器classloader+执行引擎executionengine+运行时数据区域runtimedataarea首先Java源代码文件被Java编译器编译为字节码文件,然后JVM中的类加载器加载完毕之后,交由JVM执行引擎执行。在整个

Global site tag (gtag.js) - Google Analytics