类加载器

本文详细介绍了Java程序从启动到类加载的过程,包括Bootstrap Loader如何初始化,并创建ExtClassLoader及AppClassLoader,以及它们之间的关系和各自负责加载的类路径。

一切都是由Bootstrap Loader开始:类加载器的阶层体系

 

Java程序在编译之后会产生许多的执行单位(.class),当我们执行主类时(public static void main(String arg[])方法的类),才由虚拟机一一载入所有需要的执行单位,变成一个逻辑上为一体的Java应用程序。下面将细部讨论这整个流程。

 

当我们在命令行输入java xxx.class时,java.exe根据我们之前所提过的逻辑找到JRE,接着找到在JRE之中的jvm.dll(真正的Java虚拟机),最后载入这个动态连结函数库,启动Java虚拟机。

虚拟机一启动,会先做一些初始化的动作,比方说抓取系统参数等。一旦初始化动作完成之后,就会产生第一个类加载器,即所谓的Bootstrap Loader,Bootstrap Loader是由C++编写的。这个Loader所做的初始化工作中,除了也做一些基本的初始化动作之外,最重要的就是载入定义在sun.msic命名空间底下的Launcher.java之中的ExtClassLoader(因此是inner class,所以编译之后会变成Launcher$ExtClassLoader.class),并设定其parentnull,代表其父类加载器为Bootstrap Loader。然后Bootstrap Loader再要求载入定义在sun.misc命名空间下的Launcher.java之中的AppClassLoader(因此是inner class,所以编译之后会变成Launcher$AppClassLoader.class),并设定其parent为之前产生的ExtClassLoader实例。这里需要注意的是:Launcher$ExtClassLoader.classLauncher$AppClassLoader.class都是由Bootstrap Loader所载入,所以parent和由那个类加载器载入没有关系。可以用下图表示:

 

 

AppClassLoadersun官方文件中常常又被称作系统加载器(System Loader)。最后一个步骤,是由AppClassLoader负责载入我们在命令行之中所输入的xxx.class(注意:实际上xxx.class很可能是由ExtClassLoaderBootstrap Loader载入,参考下一篇博文的【委派模型】),然后开始一个Java应用程序的生命周期。整个流程如下图:

 

这个由Bootstrap Loader-->ExtClassLoader-->AppClassLoader,就是我们所谓的类加载器的阶层体系。

 

再次强调,类加载器由谁载入(这句话有点诡异,类加载器也要由类加载器载入,这是因为除了Bootstrap Loader之外,其余的类加载器都是由Java所编写),和它的parent是谁没有关系,parent的存在只是为了某些特殊目的,这个目的之后再作解析。三个主要的加载器的关系如下图:

 

在此要注意的是,AppClassLoaderExtClassLoader都是URLClassLoader的子类。由于它们都是URLClassLoader的子类,所以它们也应该有URL作为搜索类的参考,由源代码我们可以得知:

AppClassLoader所参考的URL是从系统参数java.class.path取出的字符串所决定,而java.class.path则是由我们在执行java.exe时,利用-cp-classpathCLASSPATH环境变量所决定。在预设定情况下,AppClassLoader的搜索路径为"."(目前所在目录),如果使用-classpath(-cp等效),就可以改变AppClassLoader的搜索路径,如果没有指定-classpath,就会搜索环境变量CLASSPATH

ExtClassLoader搜索路径参考系统参数java.ext.dirs,会指向java.exe所选择的JRE所在位置下的\lib\ext子目录。

Bootstrap Loader的搜索路径由系统参数sun.boot.class.path指定。

注意:AppClassLoaderBootstrap Loader只会搜索指定的路径,不会迂回搜索这些位置下的其他路径或者没有指定的JAR文件。而ExtClassLoader会搜索底下所有的JAR文件以及classes目录,作为其搜索路径。

 

AppClassLoaderExtClassLoader在整个虚拟机中只存在一份,一旦建立了,其内部所参考的搜索路径将不再改变,也就是说,即使我们在程序里利用System.setProperty()来改变系统参数的内容,仍然无法更改搜索路径。因此,执行时期动态更改搜索路径的设定是不可能的事情。如果因为特殊需求,有些类的所在路径并非在一开始时就能决定,那么除了产生新的类加载器来辅助我们载入所需要的类之外,没有其它方法了。

【Koopman】遍历论、动态模态分解和库普曼算子谱特性的计算研究(Matlab代码实现)内容概要:本文围绕【Koopman】遍历论、动态模态分解和库普曼算子谱特性的计算研究展开,重点介绍基于Matlab的代码实现方法。文章系统阐述了遍历理论的基本概念、动态模态分解(DMD)的数学原理及其与库普曼算子谱特性之间的内在联系,展示了如何通过数值计算手段分析非线性动力系统的演化行为。文中提供了完整的Matlab代码示例,涵盖数据驱动的模态分解、谱分析及可视化过程,帮助读者理解并复现相关算法。同时,文档还列举了多个相关的科研方向和技术应用场景,体现出该方法在复杂系统建模与分析中的广泛适用性。; 适合人群:具备一定动力系统、线性代数与数值分析基础,熟悉Matlab编程,从事控制理论、流体力学、信号处理或数据驱动建模等领域研究的研究生、博士生及科研人员。; 使用场景及目标:①深入理解库普曼算子理论及其在非线性系统分析中的应用;②掌握动态模态分解(DMD)算法的实现与优化;③应用于流体动力学、气候建模、生物系统、电力系统等领域的时空模态提取与预测;④支撑高水平论文复现与科研项目开发。; 阅读建议:建议读者结合Matlab代码逐段调试运行,对照理论推导加深理解;推荐参考文中提及的相关研究方向拓展应用场景;鼓励在实际数据上验证算法性能,并尝试改进与扩展算法功能。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值