`
xlaaa111
  • 浏览: 15748 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

【转】JVM加载class文件的原理机制

    博客分类:
  • java
阅读更多
JVM加载class文件的原理机制 收藏
1.Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,
类装载器所做的工作实质是把类文件从硬盘读取到内存中

2.java中的类大致分为三种:
    1.系统类
    2.扩展类
    3.由程序员自定义的类

3.类装载方式,有两种
    1.隐式装载, 程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中,
    2.显式装载, 通过class.forname()等方法,显式加载需要的类
  隐式加载与显式加载的区别:
    两者本质是一样?,
    ?

4.类加载的动态性体现
    一个应用程序总是由n多个类组成,Java程序启动时,并不是一次把所有的类全部加载后再
运行,它总是先把保证程序运行的基础类一次性加载到jvm中,其它类等到jvm用到的时候再加载,这样的好处是节省了内存的开销,因为java最早就是为嵌入式系统而设计的,内存宝贵,这是一种可以理解的机制,而用到时再加载这也是java动态性的一种体现

5.java类装载器
    Java中的类装载器实质上也是类,功能是把类载入jvm中,值得注意的是jvm的类装载器并不是一个,而是三个,层次结构如下:
      Bootstrap Loader  - 负责加载系统类
            |
          - - ExtClassLoader  - 负责加载扩展类
                          |
                      - - AppClassLoader  - 负责加载应用类
        为什么要有三个类加载器,一方面是分工,各自负责各自的区块,另一方面为了实现委托模型,下面会谈到该模型

6. 类加载器之间是如何协调工作的
      前面说了,java中有三个类加载器,问题就来了,碰到一个类需要加载时,它们之间是如何协调工作的,即java是如何区分一个类该由哪个类加载器来完成呢。
在这里java采用了委托模型机制,这个机制简单来讲,就是“类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果Parent 找不到,那么才由自己依照自己的搜索路径搜索类”,注意喔,这句话具有递归性
下面举一个例子来说明,为了更好的理解,先弄清楚几行代码:
Public class Test{
    Public static void main(String[] arg){
      ClassLoader c  = Test.class.getClassLoader();  //获取Test类的类加载器
        System.out.println(c); 
      ClassLoader c1 = c.getParent();  //获取c这个类加载器的父类加载器
        System.out.println(c1);
      ClassLoader c2 = c1.getParent();//获取c1这个类加载器的父类加载器
        System.out.println(c2);
  }
}
把以上代码存到d:\my 文件夹下,直接编译,然后在dos模式下运行
D:\my\java Test
    。。。AppClassLoader。。。
    。。。ExtClassLoader。。。
    Null

D:\my

注: 。。。表示省略了内容
可以看出Test是由AppClassLoader加载器加载的
AppClassLoader的Parent 加载器是 ExtClassLoader

但是ExtClassLoader的Parent为 null 是怎么回事呵,朋友们留意的话,前面有提到Bootstrap Loader是用C++语言写的,依java的观点来看,逻辑上并不存在Bootstrap Loader的类实体,所以在java程序代码里试图打印出其内容时,我们就会看到输出为null
【注:以下内容大部分引用java深度历险】
弄明白了上面的示例,接下来直接进入类装载的委托模型实例,写两个文件,如下:
文件:Test1.java
Public class Test1{
    Public static void main(String[] arg){
        System.out.println(Test1.class.getClassLoader());
        Test2 t2 = new Test2();
        T2.print();
  }
}

文件: Test2.java
Public class Test2{
    Public void prin(){
        System.out.println(this.getClass().getClassLoader());
    }
}

这两个类的作用就是打印出载入它们的类装载器是谁, 将这两个文件保存到d:\my目录下,编译后,我们在复制两份,分别置于 <JRE所在目录>\classes下(注意,刚开始我们的系统下没有此目录,需自己建立) 与 <JRE所在目录>\lib\ext\classes下(同样注意,开始我们的系统下也没此目录,手工建立), 然后切换到d:\my目录下开始测试,

测试一:
<JRE所在目录>\classes下
Test1.class
Test2.class

<JRE所在目录>\lib\ext\classes下
Test1.class
Test2.class

D:\my下
Test1.class
Test2.class


dos下输入运行命令,结果如下:
D:\my>java Test1
Null
Null

D:\my>
   
    从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class. 由于 <JRE所在目录>\Classes目录为Bootstrap Loader的搜索路径之一,所以Bootstrap Loader找到了Test1.class,因此将它载入,接着在Test1.class之内有载入Test2.class的需求,由于 Test1.class是由Bootstrap Loader所载入,所以Test2.class内定是由Bootstrap Loader根据其搜索路径来找,因Test2.class也位于Bootstrap Loader可以找到的路径下,所以也被载入了,最后我们看到Test1.class与Test2.class都是由Bootstrap Loader(null)载入。


测试二:
<JRE所在目录>\classes下
Test1.class

<JRE所在目录>\lib\ext\classes下
Test1.class
Test2.class

D:\my下
Test1.class
Test2.class

dos下输入运行命令,结果如下:
D:\my>java Test1
Null
Exception in thread “main” java.lang.NoClassdefFoundError:Test2 at Test1.main。。。
D:\my>

    从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class. 由于 <JRE所在目录>\Classes目录为Bootstrap Loader的搜索路径之一,所以Bootstrap Loader找到了Test1.class,因此将它载入,接着在Test1.class之内有载入Test2.class的需求,由于 Test1.class是由Bootstrap Loader所载入,所以Test2.class内定是由Bootstrap Loader根据其搜索路径来找,但是因为Bootstrap Loader根本找不到Test2.class(被我们删除了),而Bootstrap Loader又没有Parent,所以无法载入Test2.class.最后我们看到Test1.class是由Bootstrap Loader(null)载入,而Test2.class则无法载入


测试三
<JRE所在目录>\classes下

Test2.class

<JRE所在目录>\lib\ext\classes下
Test1.class
Test2.class

D:\my下
Test1.class
Test2.class

dos下输入运行命令,结果如下:
D:\my>java Test1
。。。ExtClassLoader。。。
Null

D:\my>

    从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class.但是Bootstrap Loader无法在其搜索路径下找到Test1.class(被我们删掉了),所以ExtClassLoader只得自己搜索,因此 ExtClassLoader在其搜索路径 <JRE所在目录>\lib\ext\classes下找到了Test1.class,因此将它载入,接着在Test1.class之内有载入Test2.class的需求,由于Test1.class是由ExtClassLoader所载入,所以Test2.class内定是由 ExtClassLoader根据其搜索路径来找,但是因为ExtClassLoader有Parent,所以先由Bootstrap Loader帮忙寻找,Test2.class位于Bootstrap Loader可以找到的路径下,所以被Bootstrap Loader载入了.最后我们看到Test1.class是由ExtClassLoader载入,而Test2.class则是由Bootstrap Loader(null)载入

    了解了以上规则,请朋友们自行分析以下场景的执行结果

测试四:
<JRE所在目录>\classes下


<JRE所在目录>\lib\ext\classes下
Test1.class
Test2.class

D:\my下
Test1.class
Test2.class


测试五:
<JRE所在目录>\classes下


<JRE所在目录>\lib\ext\classes下
Test1.class


D:\my下
Test1.class
Test2.class


测试六:
<JRE所在目录>\classes下


<JRE所在目录>\lib\ext\classes下

Test2.class


D:\my下
Test1.class
Test2.class


测试七:
<JRE所在目录>\classes下


<JRE所在目录>\lib\ext\classes下


D:\my下
Test1.class
Test2.class


以上理解,错漏之处请朋友们及时指出,以免怠误大家


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/alex197963/archive/2009/08/07/4417069.aspx
分享到:
评论

相关推荐

    JVM加载class文件的原理机制

    JVM加载class文件的原理机制 Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中

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

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

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

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

    JVM执行子系统原理

    详细介绍了JVM执行子系统的工作原理,包括类文件结构与字节码指令(Class类文件结构、JVM字节码指令简介)、JVM类加载机制(类加载器、类加载时机、类加载过程)、字节码执行引擎(运行时候的栈结构、方法调用、方法...

    JVM性能优化相关面试题21道.pdf

    JVM 面试题:Java 类加载过程、JVM 加载 Class 文件的原理机制、Java内存分配

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

    JVM负责装载class文件并执行,因此,首先是JDK如何将Java代码编译为class文件、如何装载class文件及如何执行class,将源码编译为class文件的实现取决于各个JVM实现或各种源码编译器。class文件通常由类加载器...

    面试必问之jvm与性能优化

    1. 描述一下 JVM 加载 Class 文件的原理机制? 在面试java工程师的时候,这道题经常被问到,故需特别注意。 Java中的所有类,都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类,而它的工作就是把class...

    大厂真题之携程-Java高级

    描述一下 JVM 加载 Class 文件的原理机制? 在面试 java 工程师的时候,这道题经常被问到,故需特别注意。 Java 中的所有类,都需要由类加载器装载到 JVM 中才能运行。类加 载器本身也是一个类,而它的工作就是把 ...

    java基础测试.doc

    描述一下JVM加载class文件的原理机制?  每一个class文件都是一个封装的整体,可供程序员的工程通过环境变量,包的应用调用,主要分三步:装载,链接,校验; .................

    Java面试宝典

    Java面试宝典 经典题库 Java中的异常处理机制的简单原理和应用 运行时异常与一般异常有何异同? Error与Exception有什么区别? JVM加载class文件的原理机制? …………

    深入理解JVM内存结构及运行原理全套视频加资料.txt

    包括JVM执行过程、虚拟机类加载机制、运行时数据区、GC、类加载器、内存分配与回收策略等,全套视频加资料高清无密码  第1讲 说在前面的话 免费 00:05:07  第2讲 整个部分要讲的内容说明 免费 00:06:58  第3讲...

    Java进阶教程解密JVM视频教程

    * 在字节码与类加载技术章节,会从一个 class 文件开始分析其每一字节的含义。学习字节码指令的的运行流程,字节码指令与常量池、方法区的关系。掌握条件分支、循环控制、异常处理、构造方法在字节码级别的实现原理...

    JVM面试专题

    7、描述一下JVM加载class文件的原理机制? 8、Java对象创建过程 9、类的生命周期【加载过程】 10、Java 中会存在内存泄漏吗,请简单描述。 11、GC是什么?为什么要有GC? 12、做GC时,⼀个对象在内存各个Space中被...

    深入理解Java虚拟机视频教程(jvm性能调优+内存模型+虚拟机原理)视频教程

    第86节类加载机制概述00:07:26分钟 | 第87节类加载时机00:13:15分钟 | 第88节类加载的过程-加载00:15:15分钟 | 第89节类加载的过程-验证00:10:24分钟 | 第90节类加载的过程-准备00:05:40分钟 | 第91节类加载的...

    java反射机制原理详解.docx

    我们创建一个类,通过编译,生成对应的.calss文件,之后使用java.exe加载(jvm的类加载器)此.class文件,此.class文件加载到内存以后,就是一个运行时类,存在缓存区,那么这个运行时类的本身就是一个class的实例 ...

    java笔试题

    21、描述一下JVM加载class文件的原理机制? 22、char 型变量中能不能存贮一个中文汉字,为什么? 23、抽象类(abstract class)和接口(interface)有什么异同? 24、静态嵌套类(Static Nested Class)和内部类...

    Java基础加强之类加载器

    学习概述:本模块深入讲解了Java类加载方面的知识,Java类加载器和类加载机制以及类加载原理  学习目标:掌握类加载机制和原理,能够独立开发自己的类加载器。  1.类的加载  什么是类加载? 类加载是指将类的...

    Java编程经验

    2. 关于寻找class文件原理?? 建议大家在入门的时候在命令行窗口编译和运行,不要借助JCreator或者Eclipse等IDE去帮助做那些事情。尝试自己这样做: javac -classpath yourpath *.java java -classpath yourpath ...

    涵盖了90%以上的面试题

    JVM加载class文件的原理 双亲委派模型 为什么要自定义类加载器 如何自定义类加载器 什么是GC 内存泄漏和内存溢出 Java的内存模型(JVM的内存划分) JVM内存模型1.7和1.8的区别 如何判断一个对象是否是垃圾对象 垃圾...

    千方百计笔试题大全

    27、描述一下JVM 加载class 文件的原理机制? 10 28、char 型变量中能不能存贮一个中文汉字?为什么? 10 29、abstract class 和interface 有什么区别? 10 30、Static Nested Class 和Inner Class 的不同? 11 31、java...

Global site tag (gtag.js) - Google Analytics