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

JVM加载类的过程

 
阅读更多
http://www.51testing.com/?uid-225738-action-viewspace-itemid-223520

昨天,看一个build Standalone中databrusher的一个脚本,发现一个Java类似乎没有在classpath中,好像也可一直运行了。很疑惑,问了对应的开发同学,然后自己好好看了下它的代码,才知道了原理。
命令是:$JAVA_HOME/bin/java $JAVA_OPTS com.alibaba.standalone.AppStartor com.alibaba.intl.standalone.databrusher.Startor "$main_class" "$signal_file" "$recivers"
原理是:Java根据classpath找到,com.alibaba.standalone.AppStartor这个class,运行这个class,会启动一个classloader来加载com.alibaba.intl.standalone.databrusher.Startor(在里面会指定到WORLDS-INF目录下加载类),然后com.alibaba.intl.standalone.databrusher.Startor会启动对应的"$main_class".
然后,花了挺多时间好好看了一下Java的classloader,了解一下其中的原理和看了下代码。下面也简单总结一下吧。
java虚拟机是由sun.misc.Launcher来初始化的,也就是java(或java.exe)这个程序来做的.虚拟机按以下顺序搜索并装载所有需要的类:
 
1,引导类:组成java平台的类,包含rt.jari18n.jar等基础jar包中的类.
  2,扩展类:使用java扩展机制的类,都是位于扩展目录($JAVA_HOME/jre/lib/ext)中的.jar档案包.
  3,用户类:开发者定义的类或者没有使用java扩展机制的第三方产品.你必须在命令行中使用-classpath选项或者使用CLASSPATH环境变量来确定这些类的位,或者自己写ClassLoader加载

Java的class loader的大致情况如下图所示:
http://renyongjie668.blog.163.com/prevPhDownload.do?host=renyongjie668&albumId=197449439&photoId=6568564371
bootstrap classloader -->extension classloader-->system classloader
虚拟机一启动,会先做一些初始化的动作。一旦初始化动作完成之后,就会产生第一个类别加载器,即所谓的Bootstrap Loader,Bootstrap Loader 是由C++ 所撰写而成,这个Bootstrap Loader所做的初始工作中,除了也做一些基本的初始化动作之外,最重要的就是加载定义在sun.misc 命名空间底下的Launcher.java 之中的ExtClassLoader( 因为是inner class ,所以编译之后会变成Launcher$ExtClassLoader.class) ,并设定其Parent 为null,代表其父加载器为Bootstrap Loader 。然后Bootstrap Loader ,再要求加载定义于sun.misc 命名空间底下的Launcher.java 之中的AppClassLoader( 因为是inner class,所以编译之后会变成Launcher$AppClassLoader.class) ,并设定
其Parent 为之前产生的ExtClassLoader 实例。
a. Bootstrap ClassLoader/启动类加载器
主要负责java_home/jre/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作.
b. Extension ClassLoader/扩展类加载器
主要负责java_home/jre/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作
c. System ClassLoader/系统类加载器
主要负责
java -classpath/-Djava.class.path
或$CLASSPATH变量所指的目录下的类与jar包装入工作.(这里需要说明的是,如果$CLASSPATH为空,jdk会默认将被运行的Java类的当前路径作为一个默认的$CLASSPATH,一但设置了$CLASSPATH变量,则会到$CLASSPATH对应的路径下去寻找相应的类,找不到就会报错。这个结论,我已经经过测试,并且看了下类加载器中源代码)
d. User Custom ClassLoader/用户自定义类加载类(java.lang.ClassLoader的子类)在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性.(暂时理解为需要的时候才加载类,不像基础功能的类是全部预加载了)

为了有更多的了解,写了个简单的Java程序对前面三种classloader能加载类的路径及其parent类进行了测试。代码如下:
import java.net.URL;
import java.net.URLClassLoader;

 /**
 * @className: IClassLoader
 * @description: 测试三种classloader加载类的路径,及其parent
 * @author: 笑遍世界
 * @createTime: 2010-11-17 下午07:33:40
 */
public class IClassLoader {
    public static void main(String[] args) {
//        测试bootstrap classloader 的类加载路径
        URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for (int i = 0; i < urls.length; i++) {
          System.out.println(urls[i].toExternalForm());
        }
       
//        测试extension classloader 的类加载路径,先打印一个路径,再打印出其parent,然后再打印出类加载路径中的所有jar包
        System.out.println("-------------------------------------");
        System.out.println(System.getProperty("java.ext.dirs"));
        ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
        System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
        System.out.println("extension classloader can use thess jars:");
        URL[] extURLs = ((URLClassLoader)ClassLoader.getSystemClassLoader().getParent()).getURLs();
        for (int i = 0; i < extURLs.length; i++) {
               System.out.println(extURLs[i]);
        }       
       
//      测试system classloader 的类加载路径,其实也就时classpath的路径,并打印出它的parent
        System.out.println("-------------------------------------");
        System.out.println(System.getProperty("java.class.path"));
        System.out.println(ClassLoader.getSystemResource(""));
        ClassLoader systemClassloader=ClassLoader.getSystemClassLoader();
        System.out.println("the parent of system classloader : "+systemClassloader.getParent());
    }
}
 
本机(linux+jdk1.5)运行结果如下:
file:/usr/ali/java/jre/lib/rt.jar
file:/usr/ali/java/jre/lib/i18n.jar
file:/usr/ali/java/jre/lib/sunrsasign.jar
file:/usr/ali/java/jre/lib/jsse.jar
file:/usr/ali/java/jre/lib/jce.jar
file:/usr/ali/java/jre/lib/charsets.jar
file:/usr/ali/java/jre/classes
-------------------------------------
/usr/ali/java/jre/lib/ext
the parent of extension classloader : null
extension classloader can use thess jars:
file:/usr/ali/java/jre/lib/ext/emma.jar
file:/usr/ali/java/jre/lib/ext/localedata.jar
file:/usr/ali/java/jre/lib/ext/dnsns.jar
file:/usr/ali/java/jre/lib/ext/sunpkcs11.jar
file:/usr/ali/java/jre/lib/ext/sunjce_provider.jar
-------------------------------------
.:/usr/ali/java/lib/dt.jar:/usr/ali/java/lib/tools.jar
file:/home/master/workspace/2010_11/bin/
the parent of system classloader :  sun.misc.Launcher$ExtClassLoader@1a5ab41


//ps:当前路径.即是/home/master/workspace/2010_11/bin/

关于Java的classloader其原理还是需要好好理解才能清楚的,仅通过一天的了解,记录为上面那么多吧。更多详细信息,可以参考如下资料:
http://snandy.javaeye.com/blog/307083http://haofenglemon.javaeye.com/blog/426382
http://blog.csdn.net/zdwzzu2006/archive/2008/04/05/2253982.aspx
http://wuquanyin1011.javaeye.com/blog/703842
http://hi.baidu.com/yangzhibin_bai/blog/item/78846cce1cb86b0992457ead.html
http://www.blogjava.net/clraychen/archive/2008/02/20/180868.html
分享到:
评论

相关推荐

    JVM类加载过程.pptx

    JVM类加载过程

    JVM的类加载过程以及双亲委派模型详解

    主要介绍了JVM的类加载过程以及双亲委派模型详解,类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存,然后再转化为 class 对象。,需要的朋友可以参考下

    JVM加载一个类的过程

    本文主要介绍了JVM加载一个类的过程。具有很好的参考价值,下面跟着小编一起来看下吧

    CharlotteSean#JavaBooks#JVM-类加载过程1

    引言JavaGuide :一份涵盖大部分Java程序员所需要掌握的核心知识。star:45159,替他宣传一下子这位大佬,总结的真好!我引用这位大佬的文章,因为

    【JVM】类加载器与双亲委派模型

    有关类加载的全过程,可以先参考我的另外一篇文章类的奇幻漂流——类加载机制探秘 类加载器的类型 类加载器有以下种类: 启动类加载器(Bootstrap ClassLoader) 扩展类加载器(Extension ClassLoader) 应用类...

    JVM核心教程之JVM运行与类加载全过程详解

    我们都知道一个java程序运行要经过编译和执行,但是这太概括了,中间还有很多步骤,下面这篇文章主要给大家介绍了关于JVM核心教程之JVM运行与类加载全过程的相关资料,文中通过示例代码介绍的非常详细,需要的朋友...

    JVM:类加载器子系统.pdf

    总结了类加载器子系统相关的内容,主要包括类加载器子系统的作用、ClassLoader角色、加载的过程、双亲委派机制以及沙箱安全机制等内容

    JVM执行子系统原理

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

    高级开发jvm面试题和答案.pdf

    类加载过程(类加载从磁盘上将字节码文件(.class文件)中的内容读入虚拟机,并保存起来) 类加载特性 ; 类加载的时机: 三种类加载器: 双亲委派机制概念; 怎么解决双亲委派机制; 垃圾回收gc gc的标记方法; java...

    JVM(三):类加载机制(类加载过程和类加载器)1

    1.编写个向接的应程序,可能等到运时再指定其实现的类 2.户可以定义个类加载器,让程序在运时从络或其他地加载 1.加载:(重点) 1.通过“类全名”来获取定义此

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

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

    JVM思维导图(包含所有JVM知识)

    JVM整体结构内存模型(对象的创建,指针压缩,对象大小,对象内存),垃圾收集器,垃圾收集器算法、内存调优(调优工具),垃圾收集,内存回收(算法),类加载机制(类加载过程,双亲委派),一图学完JVM所有的知识...

    JVM学习笔记(一)——类的加载机制

    ​ 类加载器并不需要等到某个类被“首次主动使用”时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动...

    JVM—类加载过程学习

    1 类加载过程图解   系统加载Class类型的文件主要是:加载-&gt;连接-&gt;初始化,其中连接分为:验证-&gt;准备-&gt;解析;其实,整个生命周期是7步,类从被加载到虚拟机内存中开始,到卸载出内存为止,分为:加载-&gt;验证-&gt;准备...

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

    * 系统地学习 JVM 内存结构,垃圾回收、字节码与类加载技术。 * 在内存结构章节,能够学习掌握 JVM内存溢出现象,堆栈内存结构,利用内存诊断工具排查问题。彻底分析 StringTable的相关知识与性能优化,掌握直接内存...

    轻松搞定jvm类加载器

    而**当我们需要用到某个类时,jvm将会加载它,并在内存中创建对应的class对象,这个过程称之为类的加载。**过程如下: 类的加载、连接、初始化 1. 加载 通过类的包名和雷鸣查找到此类的字节码文件,将xx.class文件...

    深入理解JVM之类加载机制详解

    主要介绍了深入理解JVM之类加载机制,结合实例形式详细分析了类加载机制原理、过程及相关操作注意事项,需要的朋友可以参考下

    java类加载机制.xmind

    该文件是JVM中关于类加载机制的知识整理的思维导图,包括类加载机制概述、类加载的生命周期、加载时机、加载过程、类加载、类的初始化和实例化等几个大方面进行了讲解,其中类加载中还对JVM三种预定义类加载器进行了...

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

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

    分析Java类加载全过程

     其中加载(除了自定义加载)+链接的过程是完全由jvm负责的,什么时候要对类进行初始化工作(加载+链接在此之前已经完成了),jvm有严格的规定(四种情况):  1、遇到new,getstatic,putstatic,invokestatic...

Global site tag (gtag.js) - Google Analytics