热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Bootstrap、Extension、ApplicationClassLoader

BootstrapClassLoader,ExtensionClassLoader,ApplicationClassLoader三种ClassLoade

        Bootstrap Class Loader ,Extension Class Loader ,Application Class Loader三种Class Loader是JVM 系统已经事先实现。
        Bootstrap Class Loader 采用的是C或其他相应语言编写(根据JRE 操作系统版本不同而不同),其他两种Class Loader 均采用Java 语言编写,他们的实现为ExtClassLoader 与AppClassLoader 两个内部静态类,位于sun.misc.Launcher内,而Launcher则位于rt.jar中。
        以下网址可以下载JDK 的源码实现:
        http://download.java.net/openjdk/jdk6/
        通过源码可以是我们更进一步了解Class Loader 的内部实现及流程。

 

        Bootstrap Class Loader
        Bootstrap Class Loader 的实现位于${openjdk}\hotspot\src\share\vm\classfile 目录下的 classLoader.cpp 与classLoader.hpp,打开源代码可以发现Bootstrap Class Loader是采用C++ 编写的,这就是上一节代码中为什么得不到Bootstrap Class Loader 对象的原因。

        该ClassLoader 可以做到根据类文件名来加载类,这其实就和java.lang.ClassLoader 的loadClass 功能非常相近了。

ClassFileStream* ClassPathDirEntry::open_stream(const char* name) {...jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name)...
}

 

        可以看到path=_dir + 文件分隔符 + name,得到path 后,就是读取文件并存放到byte[] 的过程了。

要想path 直接可用,得有两个前提:

        (1) _dir事先已经配置好;
        (2)name 也应该先经过了处理;
        例如:
        java.lang.String,会先被转换成java/lang/String.class;
        又假如:
        _dir 为/usr/local/java/src;
        name 为com/test/HelloWorld.class;
        path 最终即为/usr/local/java/src/com/test/HelloWorld.class;


        加载类文件过程:

instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {ResourceMark rm(THREAD);EventMark m("loading class " INTPTR_FORMAT, (address)h_name());ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);stringStream st;// st.print() uses too much stack space while handling a StackOverflowError// st.print("%s.class", h_name->as_utf8());st.print_raw(h_name->as_utf8());st.print_raw(".class");char* name = st.as_string();// Lookup stream for parsing .class fileClassFileStream* stream = NULL;int classpath_index = 0;{PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),PerfClassTraceTime::CLASS_LOAD);ClassPathEntry* e = _first_entry;while (e != NULL) {stream = e->open_stream(name);if (stream != NULL) {break;}e = e->next();++classpath_index;}}instanceKlassHandle h(THREAD, klassOop(NULL));if (stream != NULL) {// class file found, parse itClassFileParser parser(stream);Handle class_loader;Handle protection_domain;symbolHandle parsed_name;instanceKlassHandle result = parser.parseClassFile(h_name,class_loader,protection_domain,parsed_name,false,CHECK_(h));// add to package tableif (add_package(name, classpath_index, THREAD)) {h = result;}}return h;
}

 

        初始化过程:

void ClassLoader::initialize() {...// lookup zip library entry pointsload_zip_library();// initialize search pathsetup_bootstrap_search_path();...
}

 

        其中load_zip_library() 即加载zip 类库,从而便于处理jar (可以认为jar 是一种特殊的zip 压缩);而setup_bootstrap_search_path() 即为初始化BootstrapClassLoader 的查找路径,其实就是在初始化上文中每个ClassPathEntry 的_dir。

        打开${openjdk}\hotspot\src\share\vm\runtime\os.cpp 文件,找到set_boot_path()方法,会发现Bootstrap Class Loader 已经将所要加载的类库jar 文件固化至代码中了,这些就是JVM 启动时必须要加载的文件。

bool os::set_boot_path(char fileSep, char pathSep) {const char* home = Arguments::get_java_home();int home_len = (int)strlen(home);static const char* meta_index_dir_format = "%/lib/";static const char* meta_index_format = "%/lib/meta-index";char* meta_index = format_boot_path(meta_index_format, home, home_len, fileSep, pathSep);if (meta_index == NULL) return false;char* meta_index_dir = format_boot_path(meta_index_dir_format, home, home_len, fileSep, pathSep);if (meta_index_dir == NULL) return false;Arguments::set_meta_index_path(meta_index, meta_index_dir);// Any modification to the JAR-file list, for the boot classpath must be// aligned with install/install/make/common/Pack.gmk. Note: boot class// path class JARs, are stripped for StackMapTable to reduce download size.static const char classpath_format[] ="%/lib/resources.jar:""%/lib/rt.jar:""%/lib/sunrsasign.jar:""%/lib/jsse.jar:""%/lib/jce.jar:""%/lib/charsets.jar:"// ## TEMPORARY hack to keep the legacy launcher working when// ## only the boot module is installed (cf. j.l.ClassLoader)"%/lib/modules/jdk.boot.jar:""%/classes";char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep);if (sysclasspath == NULL) return false;Arguments::set_sysclasspath(sysclasspath);return true;
}

 

        本人对C++ 不甚了解,所以无法就代码及流程做更进一步的讲解,希望大家谅解,也欢迎大家补充。

 

 

        AppClassLoader 与ExtClassLoader

        打开sun.misc.Launcher 的源代码,源代码位置在${openjdk}\jdk\src\share\classes\sun\misc\Launcher.java ,ExtClassLoader 与AppClassLoader 是Launcher 类的内部类,代码如下:

/*
* The class loader used for loading installed extensions.
*/
static class ExtClassLoader extends URLClassLoader {}/**
* The class loader used for loading from java.class.path.
* runs in a restricted security context.
*/
static class AppClassLoader extends URLClassLoader {}

 

        从继承关系可以向上一直追溯直至java.lang.ClassLoader 实现类,两者的继承关系如下:

java.lang.Object--- java.lang.ClassLoader--- java.security.SecureClassLoader--- java.net.URLClassLoader--- sun.misc.Launcher$ExtClassLoaderjava.lang.Object--- java.lang.ClassLoader--- java.security.SecureClassLoader--- java.net.URLClassLoader--- sun.misc.Launcher$AppClassLoader

 

        从下图可以更直观的观察出他们的继承关系(引用自网络):



 

        AppClassLoader 与ExtClassLoader 基本都是调用父类的方法,只是在其中加入了一些相应的业务逻辑,所以这里就不分析他们了,在ClassLoader这节中会更详细的分析。



推荐阅读
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文介绍了在Python中使用zlib模块进行字符串的压缩与解压缩的方法,并探讨了其在内存优化方面的应用。通过压缩存储URL等长字符串,可以大大降低内存消耗,虽然处理时间会增加,但是整体效果显著。同时,给出了参考链接,供进一步学习和应用。 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
author-avatar
flower_hj
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有