文档章节

JVM加载class文件的原理

仗剑天涯Z
 仗剑天涯Z
发布于 2015/11/25 11:36
字数 1157
阅读 19
收藏 0

        当JAVA编译器编译(Javac)为.class文件后,我们需要将class加载到JVM当中。

1、JVM加载类的过程。    

        当我们执行一个Java程序时。

        (1)、java.exe会帮助我们找到JRE,接着找到JRE内部的jvm.dll。这才是真正的Java虚拟机,最后机载动态库,激活Java虚拟机。

        (2)、虚拟机激活以后,会先做一些初始化的动作,不如读取系统参数等。一旦初始化动作完成后,就会产生第一个类装载器--Bootstrap Loader(启动类装载器)。

        (3)、Bootstrap Loader所做的初始化工作中,除了一些基本的初始化动作外,最重要的就是加载Launcher.java 之中的ExtClassLoader(扩展类装载器),并将其的Parent设为null,代表其父加载器为BootstrapLoader。

        (4)、然后Bootstrap Loader 再要求加载 Launcher.java之中的 AppClassLoader(用户自定义类装载器),并设定其Parent为之前产生的ExtClassLoader实体。这两个加载器都是以静态类的形式存在的。

            Launcher$ExtClassLoader.class 与 Launcher$AppClassLoader.class 都是由 Bootstrap Loader 所加载,所以 Parent 和由哪个类加载器加载无关。

2、类加载器体系结构

       JVM加载class文件必须通过一个叫做类装载器的程序。

        (1)、Bootstrap ClassLoader :启动类加载器,负责加载存放在%JAVA_HOME%\lib目录中的,并且被java虚拟机识别的(仅按照文件名识别,如 rt.jar,名字不符合的类库,即使放在制定路径中也不会被加载)类库到虚拟机 的内存中,启动类加载器无法被java程序直接引用。

        (2)、Extension ClassLoader:扩展类加载器。由sun.misc.Launcher$ExtClassLoader实现,负责加载%JAVA_HOME%\lib\ext目录中的类库,开发者可以直接使用扩展类加载器。

        (3)、Application ClassLoader:应用程序类加载器,由sun.misc.Launcher$AppClassLoader实现,负责加载用户类路径classpath上所指定的类库,是类加载器ClassLoader中的getSystemClassLoader()方法的返回值,开发者可以直接使用此加载器。如果程序中没有自定义过类加载器,该加载器就是程序中默认的类加载器。

    注:上述三个JDK提供的类加载器虽然是父子类加载器关系,但是没有使用继承,而是使用了组合关系。  

3、双亲委派模式(ParentsDelegation Model)   (双亲并不是两个 。而是父类们。。) 

                                   

         用户自定义类装载器经常依赖其他类装载器--至少依赖虚拟机启动时创建的启动装载器来帮助他实现一些类装载请求。

         在版本1.2之后,类装载器请求另一个类装载器来装载类型的过程被形式化,称为双亲委派模式。

          除启动类装载器之外的每一个类装载器,都有一个'双亲'类装载器,在某个特定的类装载器试图已常用方式装载类型以前,它会先默认的将其分配给它的双亲-请求它的双亲来装载这个类型。这个双亲再一次请求他的双亲来装载这个类型。这个委派的过程一直向上继续,直到达到启动类装载器。

   package test; 
    import java.net.URL; 
    import java.net.URLClassLoader; 
    public class ClassLoaderTest { 
        private static int count = -1; 
        public static void testClassLoader(Object obj) { 
            if (count < 0 && obj == null) { 
               System.out.println("Input object is NULL"; 
               return; 
           } 
            ClassLoader cl = null; 
            if (obj != null && !(obj instanceof ClassLoader)) { 
                cl = obj.getClass().getClassLoader(); 
            } else if (obj != null) { 
                cl = (ClassLoader) obj; 
            } 
            count++; 
            String parent = ""; 
            for (int i = 0; i < count; i++) { 
                parent += "Parent "; 
            } 
            if (cl != null) { 
                System.out.println( 
                    parent + "ClassLoader name = " + cl.getClass().getName()); 
                testClassLoader(cl.getParent()); 
            } else { 
               System.out.println( 
                    parent + "ClassLoader name = BootstrapClassLoader"; 
               count = -1; 
            } 
       } 
        public static void main(String[] args) { 
            URL[] urls = new URL[1]; 
            URLClassLoader urlLoader = new URLClassLoader(urls); 
            ClassLoaderTest.testClassLoader(urlLoader); 
       } 
  }

        以上例程的输出为:
            ClassLoader name = java.net.URLClassLoader
            Parent ClassLoader name = sun.misc.Launcher$AppClassLoader
            Parent Parent ClassLoader name = sun.misc.Launcher$ExtClassLoader
            Parent Parent Parent ClassLoader name = BootstrapClassLoader


4、由于是找到最上层的加载器来加载所以当类重复时会不会加载我们自定义的类的。

    

package java.lang;

public class String {
	public static void main(String[] args){
		
	}
}


         java.lang.NoSuchMethodError: main
                     Exception in thread "main"

      


结论:我们当然可以自定义一个和API完全一样的类,但是由于双亲委托模型,使得我们不可能加载上我们自定义的这样一个类。所以J2SE规范中希望我们自定义的包有自己唯一的特色(网络域名)。还有一点,这种加载器原理使得JVM更加安全的运行程序,

        

© 著作权归作者所有

下一篇: 归并排序
仗剑天涯Z
粉丝 1
博文 14
码字总数 6260
作品 0
昌平
程序员
私信 提问
深入分析Java ClassLoader原理

一、什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程序的一个...

5W1H-
2013/05/27
1K
2
【JVM系列】一步步解析java执行内幕

对于任何一门语言,要想达到精通的水平,研究它的执行原理(或者叫底层机制)不失为一种良好的方式。在本篇文章中,将重点研究java源代码的执行原理,即从程 序员编写JAVA源代码,到最终形成产...

java菜分享
03/02
21
0
深入分析 Java ClassLoader 原理

一、什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程序的一个...

passionfly
2015/04/16
166
1
[Java] JAVA和JVM运行原理

JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器。它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行java的字节码程序。 编译器负责把Jav...

枫兮兮
2014/03/12
1K
3
深入分析Java ClassLoader原理

一、什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是 BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程序的一个...

alexgaoyh
2014/04/28
163
1

没有更多内容

加载失败,请刷新页面

加载更多

让《强化学习(第2版)》架起一座通往强化学习经典知识宝库的桥梁

上交大计算科学与工程系俞凯教授,5分钟口述讲解,带你快速认识了解年度重磅图书《强化学习(第二版)》! 在 AlphaGo战胜李世石之后,AlphaZero以其完全凭借自我学习超越人类在各种棋类游戏...

博文视点Bv
17分钟前
5
0
TLA7-EVM开发板的处理器、NOR FLASH、DDR3

TLA7-EVM开发板是一款由广州创龙基于Xilinx Artix-7系列FPGA自主研发的核心板+底板方式的开发板,可快速评估FPGA性能。核心板尺寸仅70mm*50mm,底板采用沉金无铅工艺的6层板设计,专业的PCB...

Tronlong创龙
25分钟前
4
0
UUID的变种-有序

为了解决UUID无序的问题,NHibernate在其主键生成方式中提供了Comb算法(combined guid/timestamp)。保留GUID的10个字节,用另6个字节表示GUID生成的时间(DateTime)。 /// <summary> //...

Canaan_
26分钟前
4
0
Netty学习(6)——通道间数据传输

1. FileChannel实现通道间的数据传输 在Java NIO中,如果两个通道中有一个是FileChannel,那你可以直接将数据从一个channel传输到另外一个channel。 transferFrom() FileChannel的transferF...

江左煤郎
30分钟前
3
0
AngularDOM操作

gtandsn
30分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部