`
pleasetojava
  • 浏览: 739199 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

动态装载问题的研究

阅读更多
1 问题背景
我们都知道,Java平台一大亮点就在于其类装载器体系结构,这使得JVM可以在运行期从Java API,扩展路经(java.ext.path),classpath以及用户指定的位置(文件或网络)中载入所需的class,从而达到动态装载的目的。然而其类装载器委托模型在保证了安全性和强大功能的同时,也导致了相当的复杂性,有很多地方一旦我们不加注意的话就将导致错误。这里我希望通过一些小例子来展示动态装载的某些方面,深入地了解一下怎么进行动态装载,会遇到什么样的问题,并就问题的原因与解决方法进行讨论。
也许有人会说:我的程序不用什么动态装载,平时运行程序就是java –classpath … myPkg.my不就行了吗?不过我总是听前辈说,要想完全了解一个系统下的程序设计,就必须要深入研究这个平台的特性,做到心中有数,做起程序才不会处处制肘。类的动态装载是Java平台最显著的特征之一,许多著名的项目—Tomcat,Eclipse都使用自定义类装载器来装载运行时所需的类,如果连什么是动态装载和怎么动态装载都没弄明白,还能去玩自定义类装载器吗?所以还是不要浮躁,让我们从基础开始做起吧。
不过,我要说明的是你在看我这篇文章之前最好先熟悉一下Java的类装载器体系结构以及其委托模型,我在这里将不加赘述,推荐先看《Java深度历险》或《深入Java虚拟机》的第八章。
2 问题研究
我要讨论的问题是:让一个在my/目录下名为my.Main的类在运行期读取util/中的util.Tool类。
l 实验一
我的实验目录结构如下
其中my.Main的代码如下:
util.Tool的代码如下:
在my.Main的代码中16行可以看到,我定义了一个URLClassLoader,想要读取在同一根目录下的/util/Tool.class,接下来我们运行如下命令,来查看运行结果:
如上可见,util.Tool被顺利装载了,可是装载它的却是AppClassLoader,而不是我们想要的URLClassLoader!这是为什么呢?
原因很简单,因为我们将util/Tool.class放到了JVM系统变量”user.dir”所指定的目录下,而该JVM系统变量的默认值为程序所在的根目录,相当于把classpath 设置成了”.”,也就是相当于执行了命令:
java –classpath . my.Main
于是,正因为util.Tool在classpath下,于是JVM就在在载入my.Main的同时也用AppClassLoader将util.Tool载入到JVM了。我们可以通过如下命令看得更清楚一些:
java –verbose my.Main
看到了吗?由于AppClassLoader预先载入了util.Tool类,而且在URLClassLoader的loadClass()方法中有如下语句:Class cls = getLoadedClass(String className);如果cls!=null的话,loadClass()就会返回已经载入过的(即由AppClassLoader所载入的)util.Tool类,所以我们才会看到以上结果。
l 实验二
为了解决以上问题,我决定按如下方式组织我的目录结构
然后对Main.class进行一些修改:
嗯,这下我们不会为util.Tool被提前载入而烦恼了,因为载入my.Main的AppClassLoader找不到换了位置的util.Tool类了。这回可能有人会问:subdir不是还在”user.dir”所指向的目录下吗?怎么只是多建了一层目录它就找不到了呢?原因是AppClassLoader是URLClassLoader的子类,它在载入class的时候也是根据该类的URL来进行定位的。那我们的例子来说,在“实验一”的最后一个图中我们可以看到,util.Tool被载入的位置为:file1:c:/Test1,JVM得到这个URL之后,将util.Tool中的”.”变为”/”,在所得字符串结尾处加上”.class”,最后将该字符串加到file1:c:/Test1后面,就得到了最终util.Tool的URL:file1:c:/Test1/util/Tool.class。而当加了一层subdir目录之后,AppClassLoader就找不到file1:c:/Test1/util/Tool.class了,而只能由程序中定义的URLClassLoader来载入。
这时我们运行程序,所得结果如下:
可以看到,util.Tool确实已经我定义的URLClassLoader被载入并初始化了,可是为什么最后却有一个奇怪的异常呢?NoClassDefFoundError?util.Tool类不是都载入了吗?怎么还找不到它的定义呢?
这个问题需要从JVM的装载机制说起。对于每个JVM实例,除了内置的三个内置的类装载器(BootStrapClassLoader,ExtClassLoader,AppClassLoader)之外,还可能有一些用户自定义的类装载器,而这些类装载器可能在一个程序运行周期内载入同一个类,即AppClassLoader和我自定义的类装载器MyClassLoader可能同时需要载入util.Tool类。为了避免冲突,JVM为每个类装载器都建立一个命名空间,并以此作为其访问边界。例如,如果my.Main想要引用util.Tool类,则它们必须是由同一装载器载入的,也就是说,由于my.Main是由AppClassLoader载入的,那么util.Tool也必须由AppClassLoader载入才行,否则就会出现上述错误。
问题解决的方法很简单,只需要让my.Main和util.Tool由同一类装载器载入就行了。
l 实验三
为了让my.Main和util.Tool由同一类装载器载入,我定义了一个启动类—boot.BootStrap类:
在这里,我用自己的类装载器ucl来装载my.Main类,并用reflection API来调用其main()方法,同时也对my.Main稍作修改
然后执行一下看看结果:
图中可以很清楚的看到BootStrap类则是由AppClassLoader载入的,而Main类和Tool类都是由同一个URLClassLoader在运行期动态载入的。至此,我们完成了对类的动态载入的全部说明和实验,希望对你能有所帮助。
分享到:
评论

相关推荐

    轮船装载问题(回溯法与动态规划法的综合)

    ### 轮船装载问题(回溯法与动态规划法的综合) #### 实验背景与目标 本实验针对轮船装载问题,通过结合回溯法和动态规划法两种不同的算法来寻找最优解。轮船装载问题是一种经典的组合优化问题,在实际场景中广泛...

    装载问题的算法

    装载问题(也称为背包问题)是计算机科学与运筹学中一个经典的问题,主要研究如何在有限的资源下,通过选择最优的组合方式来达到最大的效益。在本例中,目标是在不超过船的最大载重量的情况下,尽可能多地装载货物。...

    求解装载问题.rar

    装载问题,又称装箱问题或装载优化问题,是运筹学和计算机科学中的一种经典问题。在实际应用中,它通常出现...通过深入研究并理解这个解决方案,不仅可以掌握装载问题的解决策略,还能提升在实际问题中应用算法的能力。

    论文研究-机动车辆装载问题的一种混合遗传算法实现.pdf

    针对货物装载地和运送目的地均已确定情况下的车辆装载问题,给出了基于遗传算法求解的数学模型,并对基本遗传算法的各个算子针对问题的特点提出了改进方法,同时引入启发式策略,形成了一种混合遗传算法。...

    算法实验报告 集装箱的装载问题

    在IT领域,优化问题是一个广泛研究的课题,而“集装箱的装载问题”是其中的一个典型实例,涉及到空间利用效率最大化的问题。这个问题的核心是如何在给定的三维空间内,有效地安排一系列圆柱形物体(在这里是木材)以...

    java装载问题算法

    Java装载问题,也称为装载问题或装载平衡问题,是一个经典的优化问题,主要研究如何将一组物品装入最小数量的容器中,使得每个容器的装载量不超过其最大容量,并且尽可能地减少使用的容器数量。在Java编程中,解决这...

    掘进机星轮装载机构的设计研究

    通过这些理论的应用,可以解决实际设计和研究中遇到的各种问题,例如优化星轮的表面处理以减小摩擦、选择合适的材料以提高耐磨性、设计合理的传动机构以确保转速的精确控制等。 对于星轮装载机构的设计研究,还应该...

    算法设计与分析 报告 一.rar_greedy_最优装载问题_算法设计与分析_贪心 算法_贪心算法

    "算法设计与分析 报告 一.doc"可能包含了一份详细的研究报告,深入探讨了贪心算法在最优装载问题中的具体实现步骤、性能分析以及可能遇到的问题。报告中可能还涵盖了算法的时间复杂度和空间复杂度的计算,以及与其他...

    装载机工作装置强度分析

    模态分析主要用于研究结构的固有特性,如固有频率、振型等。通过模态分析,可以了解动臂在振动过程中的动态行为。 1. **设定模态分析类型**:选择合适的模态分析类型,如自由模态分析或强迫响应分析。 2. **施加...

    数据结构课设-箱子装载问题的最优解

    解决箱子装载问题的常用算法有贪心算法、回溯法、动态规划等。具体实现中,可能采用以下策略: 1. 贪心算法:每次尝试将最大重量的物品放入当前可用的箱子,但这种策略可能无法得到全局最优解。 2. 回溯法:通过...

    装载机可靠性分析及工作装置动态仿真.doc

    本文从装载机可靠性分析和工作装置动态仿真两个方面进行研究,旨在为装载机的设计、制造和维护提供理论依据和技术支持。 一、可靠性分析 可靠性是指产品在规定的条件下和规定的时间内,完成规定功能的能力。对于...

    煤矿立井装载用板式定量输送机的仿真分析

    针对国内首套50t煤矿立井装载用板式定量输送机的研制,采用基于DEM的流动性分析方法模拟样机运行速度和物料堆积尺寸在...上述研究结果为样机设计奠定基础,可为煤矿立井装载用板式定量输送机顺利试制和实验提供参考依据。

    轮式装载机动臂强度实验研究.pdf

    此外,这些研究结果不仅对中原180—05型轮式装载机具有直接的指导意义,也为其他型号装载机的设计和研究提供了有价值的参考。 总结而言,轮式装载机动臂强度的科学实验研究,对于提高装载机在工程应用中的性能和...

    基于MSP430单片机的装载机车载称重系统的研究.docx

    本研究利用MSP430系列单片机为核心构建了一套车载称重系统,以实现装载机在工作过程中的动态称重。 MSP430单片机是德州仪器(Texas Instruments)推出的一款低功耗、高性能的微控制器,适用于各种嵌入式应用。它...

    基于Matlab GUI的装载机动力总成建模与仿真.pdf

    根据提供的文件信息,本篇文章主要围绕“基于Matlab GUI的装载机动力总成建模与仿真”进行研究,这涉及到机械工程、计算机仿真以及Matlab软件的实际应用。以下为详细的知识点: 1. 装载机动力总成建模:动力总成是...

Global site tag (gtag.js) - Google Analytics