当前位置: 首页 > news >正文

小研究 - JVM 的类装载机制

本文通过对一个类装载实例的分析,阐明了 Java虚拟机的类装载的代理机制和由此定义的命名空间,指出了类装载机制在容器/组件/抽象框架结构中的作用。

目录

1  引言

2  实例

3  分析

3.1  类装载的代理机制

3.2  Java的命名空间

3.3  解决问题

4  应用

4.1  容器组件抽象框架

4.2  类装载器和容器组件抽象框架

5  结论


1  引言

Java虚拟机 JVM)的类装载就是指将包含在类文件中的字节码装载到JVM中,并使其成为JVM一部分的过程口。JVM 的类动态装载技术能够在运行时刻动态地加载或者替换系统的某些功能模块,而不影响系统其他功能模块的正常运行。类的动态加载是 JVM 的一项非常重要的技术,是许多企业 Java技术的基础,应用它可以以相对简单、灵活的形式来构建复杂的企业级应用。类的动态加载技术和具有部分类似功能的动态链接库技术相比,具有灵活、面向对象、平台独立等优点。

2  实例

下面是有关 JVM 的类动态装载技术的一个例子,包括:一个类装载器(CL. java)、一个接口(A. java)和一个实现类B. java)。代码的主要部分如下:

/CL.java
publicclassCLextendsClassLoader{protectedClassfindClass)Stringname)throwsClassNot-
FoundException{
byte[]b=loadClassData(name);
returndefineClass(name,b,0,b.length);}privatebyte[]loadClassData(Stringname)throwsClass-
NotFoundException{//获取并返回指定类的字节码…}publicstaticvoidmain(Stringargs[])throwsException{
Classb=newCL().loadClass(arg[0]);
Aa=(A)b.newInstance();//59行
a.f()}
}
//A.java
publicinterfaceA{publicvoidf();
}
//B.java
publicclassBimplementsA {publicvoidf(){
System.out.println("B.f()");}
}

其中,实现类B不在类路径(CLASSPATH)中,并且是到运行时才给出的。用 JDK 1.2以上版本的 Java编译器编译以上代码,然后运行:

>javaCLB

如果如下:

b.f()

可见,类装载器CL已经成功地将类B装载到JVM中。JVM也成功地激活了类 B中的方法。在这个过程中,Java的类装载子系统实现上完成了三个步骤:装载、链接和初始化。其中链接又可以分为校验(Verification)、准备Prepara tion)和决定Resolution)三步。除决定外,其他步骤是严格按顺序完成的。各步骤的主要工作如下:

装载:查找和导入类或接口的二进制数据。

链接:执行下面的校验、准备和决定步骤,其中决定步骤是可选的。

校验:检查导入类或接口的二进制数据的正确性。

准备:给类的静态变量分配并初始化存储空间。

决定:将符号引用转成直接引用。

初始化:激活类的静态变量的初始化Java代码和静态Java代码块。

JVM 的类装载子系统的更多介绍可参见资料。

根据Java2的扩展机制3,将CL. class文件打包成clja文件,并将cl jar文件放在Java执行环境的扩展目录通常为<JAVA-HOME> /jre/lib/ext具体可查看运行时环境变量java ext dirs值)中。

当再次执行以上程序:

> java CL B

结果如下:(第59行已在代码中标出)

Exception in thread "main" java.lang.NoClassDef-
FoundError:A
atCL.main(CL.java:59)

抛出的例外指明类A没有找到,可是类A确实在类路径(CLASSPATH)中。而在将cl jar文件放在Java执行环境的扩展目录之前,程序运行正确。那么,从类路径CLASSPATH装载类和从Java扩展目录装载类到底有什么不同呢?

3  分析

3.1  类装载的代理机制

Java2的类装载模型是一种代理(delegation,有人译成委托)模型3.当JVM要求类装载器L1装载一个类时,L1首先将这个类装载请求转发给他的父装载器。只有当父装载器没有装载并无法装载这个类时,L1才获得装载这个类的机会。这样,所有类装载器的代理关系构成了一棵树。树的根是类的根装载器(bootstrap Class Loader),在JVM中他以"null表示。除根装载器以外的类装载器有且仅有一个父装载器。在创建一个装载器时,如果没有显式地给出父装载器,那么JVM将默认系统装载器为其父装载器。Java2的基本的类装载器代理结构如图1所示。

根Bootstrap)装载器:从sun boot class path装载运行时类库的核心代码;是JVM的一部分,没有父装载器。

扩展(Extension)装载器:从 java ext dirs 扩展目录)中装载代码;父装载器为根装载器;用纯Java代码实现。

系统(System orApplication)装载器:从java class path(CLASSPATH环境变量)装载代码;父装载器为扩展装载器;用纯Java代码实现;是用户自定义类装载器的缺省父装载器。

小应用程序(Applet)装载器:从用户指定的网络上的特定目录装载小应用程序代码;父装载器为系统装载器。

一个好的类装载器应该满足以下二个性质2

1)对于相同的类名,类装载器应该返回同一个类对象。

2)如果类装载器 L1将装载类 C的请求转给类装载器L2,那么对于以下的类或接口 T,L1和 L2应该返回同一个类对象:

aT为 C的直接超类;

b)T 为 C的直接超接口;

cT为 C的成员变量的类型;

d)T为C的成员函数或构建器的参数类型;

e)T为C的成员函数的返回类型

每个已经装载到JVM中的类都隐含有装载他的类装载器的信息。类方法getC lassLoader可以得到装载这个类的类装载器。已经装载到JVM中的类不能更改他的类装载器。一个类装载器认识的类包括他的父装载器认识的类和他自己装载的类。一个类装载器认识的类是他自己装载的类的超集。

Java2中的类的装载过程是代理装载的过程。比如:W el浏览器中的JVM需要装载一个小应用程序SampleApplet JVM调用小应用程序装载器ACL来完成装载。ACL首先请求他的父装载器,即系统装载器装载SampleApplet由于SampleA pplet不在系统装载器的装载路径中,所以系统装载器没有找到这个类,也就没有装载成功。接着ACL自己装载SampleApplet ACL通过网络成功地找到了SampleApplet class文件并将他导入到了JVM中。在装载过程中,JVM发现SampleApplet是从超类java applet Applet继承的。所以JVM再次调用ACL来装载java applet Applet类。ACL又再次按上面的顺序装载Applet类,结果ACL发现他的父装载器已经装载了这个类,所以ACL就直接将这个已经装载的类返回给了JVM,完成了Applet类的装载。接下来, Applet类的超类也一样处理。最后, SampleA pplet及所有有关的类都装载到了 JVM 中。

3.2  Java的命名空间

从类装载的代理机制可以看出:在Java中,不同的类装载器定义了不同的命名空间。并且这些由类装载器定义的命名空间会有部分重叠,这保证了面向对象技术的一些重要特性,比如继承和多态的实现同。可以想象,如果没有这种父装载器首先获得装载权利的代理机制,而是所有的类装载器都各自装载,那么各个类装载器装载到JVM中的类都相互无关。JVM 本身的一些基本的类,如java lang. Object类在每个类装载器的命名空间中都得保留一个副本。并且更为严重的是,这些不同命名空间中的类被完全隔离开来了,他们之间不能进行任何形式的交互,也就不存在继承、多态等一些面象对象的关键特性。

3.3  解决问题

理解了类装载的代理机制和Java的命名空间后,再看本文前面的实例中抛出的例外,就很显然了。将cl jar文件放在Java执行环境的扩展目录以前,从命令行运行程序 CL,JVM首先调用系统类装载器装载CL类,由于系统装载器的父装载器是扩展类装载器,所以扩展类装载器先于系统类装载器获得装载CL的机会,可是扩展装载器在他的装载目录中没有找到 CL类的定义,接着,系统类装载器获得装载 CL类的机会,由于CL类在系统路径中,所以系统类装载器最终装载了类CL。类 A在类CL中被引用,其装载过程和类CL的装载过程完全一致。

从 java命名空间的划分来看,在将 cl jar文件放在 Java执行环境的扩展目录以前和以后。类CL和类A在Java的命名空间的位置如图2所示。

对类装载的代理机制和 Java的命名空间的理解能够加深对Java语言的认识。比如:有时会听到这样的表述:“一个Java类可由它的全名包名+.+类名)唯一标识”。这种表述只有在同一命名空间中是正确的,如果要在所有命名空间中都成立,须如下表述:“一个 Java类可由它的全名包名+.+类名)和它的类装载器唯一标识”。

4  应用

4.1  容器组件抽象框架

抽象框架是容器和由容器管理的组件之间的某种约定。通常,容器为组件提供了一些公共服务,如激活、生命周期、持久性、安全、事务等回。比如:一个Java兼容的WEB浏览器给小应用程序提供了激活和生命周期服务。这时,java applet包就是抽象框架,用户写的特定的小应用程序就是组件,浏览器就是容器。注意:java applet包中的Applet类是抽象的。容器和组件间的接口的定义通常是抽象的,这也是为什么称抽象框架的原因。

4.2  类装载器和容器组件抽象框架

为了实现容器组件抽象框架这种架构,关键的一点是要确保定义抽象框架的抽象类由唯一的类装载器装载,并且对所有需要引用抽象框架的抽象类的类装载器可见。这样就保证了容器中引用的抽象框架和组件中引用的抽象框架是同一个抽象框架,也满足了面向对象的继承、多态特性。通常,定义抽象框架的抽象类由实现他的组件的类装载器的父装载器来装载。如在Servlet兼容的WEB服务器中,将装载Servle抽象框架类的某个核心类装载器作为所有 Servlet类的父装载器。容器 /组件 /抽象框架和类装载器的关系如图3所示。图3可以看出,类装载器的代理机制从逻辑上保证了容器/组件抽象框架这三者关系的正确实现。

5  结论

类的动态装载机制是 JVM 的一项核心技术,也是容易被忽视而引起很多误解的地方。只有深刻地理解了类装载的代理机制以及由此引出的Java命名空间,才能更加灵活、可靠、有效地构建复杂的企业级应用。

相关文章:

小研究 - JVM 的类装载机制

本文通过对一个类装载实例的分析&#xff0c;阐明了 Java虚拟机的类装载的代理机制和由此定义的命名空间&#xff0c;指出了类装载机制在容器/组件/抽象框架结构中的作用。 目录 1 引言 2 实例 3 分析 3.1 类装载的代理机制 3.2 Java的命名空间 3.3 解决问题 4 应…...

项目---日志系统

目录 项目系统开发环境核心技术日志系统介绍为什么需要日志系统? 日志系统框架设计日志系统模块划分代码实现通用工具实现日志等级模块实现日志消息模块实现格式化模块实现落地模块实现日志器模块同步日志器异步日志器缓冲区实现异步工作器实现 回归异步日志器模块建造者模式日…...

设计模式--建造者模式(Builder Pattern)

一、什么是建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它关注如何按照一定的步骤和规则创建复杂对象。建造者模式的主要目的是将一个复杂对象的构建过程与其表示分离&#xff0c;从而使同样的构建过程可以创建不同的表示。…...

若依vue打印的简单方法

像我们后端程序员做前端的话,有时候真不需要知道什么原理,直接塞就好了 我们选用基于hiprint 的vue-plugin-hiprint来打印 目的是为了实现点击某些行的数据,然后点击某个按钮直接弹出下面的打印 此链接 大佬是原创,我拿来总结梳理一下 插件进阶功能请移步: 链接 插件模板制作页…...

Rust 基础语法学习

Rust 基础语法学习 文章目录 Rust 基础语法学习hello world变量数据类型整数类型进制表示方法浮点数类型布尔类型字符类型字符串复合类型元组结构体元组结构体 切片类型字符串切片数组切片 不可变变量与可变变量常量注释函数语句与表达式 流程控制语句if else条件判断while循环…...

iOS开发Swift-函数

1.函数的定义和调用 func greet(person: String) -> String { // 函数名 传入值 传入值类型 返回值类型let greeting "Hello" personreturn greeting } print( greet(person: "Anna") ) //调用2.函数的参数与返回值 (1)无参函数 func sayHe…...

序列化协议:JSON和XML

作者&#xff1a;CARROT 链接&#xff1a;https://www.zhihu.com/question/604811576/answer/3100483698 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 json和xml都是数据传输的格式。比如我们开发过程中需要和网…...

江西萍乡能源石油化工阀门三维扫描3d测量抄数建模-CASAIM中科广电

长期以来&#xff0c;石油天然气、石油石化、发电和管道输送行业在环保、健康和安全保障方面一直承受着巨大的压力&#xff0c;他们必须确保相关规程在各项作业中得到全面贯彻。 阀门作为流体管道运输中的组成部分&#xff0c;其装配密封度是保证流体运输安全的重要一环&#…...

Go【gin和gorm框架】实现紧急事件登记的接口

简单来说&#xff0c;就是接受前端微信小程序发来的数据保存到数据库&#xff0c;这是我写的第二个接口&#xff0c;相比前一个要稍微简单一些&#xff0c;而且因为前端页面也是我写的&#xff0c;参数类型自然是无缝对接_ 前端页面大概长这个样子 先用apifox模拟发送请求测试…...

第一个VUE程序?

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title></head> <body><div id"app">{{message}} </div><!-- 1.导入Vue.js --> <script s…...

电阻器件的分类

电阻器的种类碳膜电阻膜式电阻器中的一种。气态碳氢化合物在高温和真空中分解&#xff0c;碳沉积在瓷棒或者瓷管上&#xff0c;形成一层结晶碳膜。改变碳膜厚度和用刻槽的方式变更碳膜的长度可以得到不同的阻值。碳膜电阻成本较低&#xff0c;电性能和稳定性较差&#xff0c;一…...

QT基础教程之二 第一个Qt小程序

QT基础教程之二 第一个Qt小程序 按钮的创建 在Qt程序中&#xff0c;最常用的控件之一就是按钮了&#xff0c;首先我们来看下如何创建一个按钮 QPushButton * btn new QPushButton; 头文件 #include <QPushButton>//设置父亲btn->setParent(this);//设置文字btn-&g…...

Edge用户数据目录查找

创建 Microsoft Edge 用户数据目录变量...

最新外卖霸王餐小程序、H5、微信公众号版外卖系统源码|霸王餐美团/饿了么系统/外卖红包cps粉丝裂变玩法源码下载

最新外卖霸王餐小程序、H5、微信公众号版外卖系统源码、霸王餐美团、饿了么系统&#xff0c;粉丝裂变玩源码下载&#xff0c;外卖cps小程序项目&#xff0c;外卖红包cps带好友返利佣金分销系统程序、饿了么美团联盟源码&#xff0c;外卖cps带分销返利后端源码&#xff0c;基于L…...

数据库事务四大特性

事务的4大特性&#xff08;ACID&#xff09;&#xff1a; 原子性(Atomicity)&#xff1a; 事务是数据库的逻辑工作单位&#xff0c;它对数据库的修改要么全部执行&#xff0c;要么全部不执行。 一致性(Consistemcy)&#xff1a; 事务前后&#xff0c;数据库的状态都满足所有的完…...

浅谈Router和Route

router 和 route 是在前端框架中用于管理和处理路由的两个关键概念。这两者之间的关系可以通过具体的代码来解释。在本示例中&#xff0c;我将使用 React 和 React Router 来说明它们之间的关系。 Router&#xff08;路由器&#xff09;&#xff1a;Router 是一个库或框架&…...

Linux环境安装jdk

1.安装jdk 上传jdk.tar.gz;安装包在下载内容里可以直接下载tar -zxvf jdk.tar.gz;配置环境变量&#xff1a;vi /etc/profile&#xff1b;填入以下内容&#xff1b;退出编辑模式&#xff0c;保存&#xff1b;然后source /etc/profile使配置生效&#xff1b; export JAVA_HOME/d…...

数据隐私与安全在大数据时代的挑战与应对

文章目录 数据隐私的挑战数据安全的挑战应对策略和方法1. 合规和监管2. 加密技术3. 匿名化和脱敏4. 安全意识培训5. 隐私保护技术 结论 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&…...

vue3 基础知识 (生命周期) 06

你好&#xff01; 文章目录 一、生命周期二、生命周期过程三、组件的 v-model 一、生命周期 每个组件都可能从 创建、挂载、更新、卸载 等一系列的过程 在这个过程中的某一个阶段&#xff0c;用于可能会想要 添加一些属于自己的代码逻辑&#xff08;比如组件创建完成后请求一些…...

【Eclipse】汉化简体中文教程(官方汉化包,IDE自带软件安装功能),图文详情

目录 0.环境 1.步骤 1&#xff09;查看eclipse的版本 2&#xff09;在官网找语言包&#xff0c;并复制链接 3&#xff09;将链接复制到eclipse中 4&#xff09;汉化完成 0.环境 windows11&#xff0c;64位&#xff1b; eclipse 2021-6版本 1.步骤 思路&#xff1a;在官网找…...

Kotlin协程flow的debounce参数timeoutMillis特性

Kotlin协程flow的debounce参数timeoutMillis特性 <dependency><groupId>org.jetbrains.kotlinx</groupId><artifactId>kotlinx-coroutines-core</artifactId><version>1.7.3</version><type>pom</type></dependency&…...

oracle 12c怎样修改varchar2允许的最大长度

12C单实例测试&#xff0c;varchar2在早期版本中最大长度限制为4000&#xff0c;当字段长度指定的比较长的时候会报错&#xff1a;ORA-00910: specified length too long for its datatype。 早期版本中虽然SQL数据类型限制为4000&#xff08;如表中的列的varchar2类型&#x…...

python WSGI和ASGI的区别

用户到我们web应用中间经过的相关协议&#xff0c;具体介绍和pyhton相关的WSGI和ASGI&#xff0c;我先把结论列出来&#xff0c;详细描述请看下面介绍&#xff01; 请大家先记住这张图&#xff0c;带着问题和整个框架去看比较易于了解 CGI&#xff0c;WSGI&#xff0c;ASGI、…...

【Golang】什么是内存逃逸?

文章目录 要从C/C谈起Golang的内存逃逸 要从C/C谈起 在C/C中&#xff0c;局部变量被分配到栈区&#xff0c;一旦当前函数执行完毕&#xff0c;局部变量占用的内存也将被释放&#xff0c;因此以下代码无法将数组的内容传递出去。 int *getArray() {int array[7] {1, 2, 3, 4,…...

MVC OR DDD

MVC OR DDD 说明&#xff1a;这篇是标题党&#xff0c;不包含相关概念说明 前段时间跟随师兄学习了解了DDD领域驱动模型&#xff0c;觉得这个思想更好&#xff0c;进行下面解析和学习方面的思考和实践&#xff0c;觉得很好&#xff0c;耐心读下去。希望对您有所帮助。 首先&am…...

前端面试:【TypeScript】静态类型检查与编译时类型检查

TypeScript是一种由Microsoft开发的编程语言&#xff0c;它在JavaScript的基础上添加了强大的静态类型系统。在本文中&#xff0c;我们将深入探讨TypeScript的静态类型检查和编译时类型检查&#xff0c;以及它们如何提高代码的可靠性和可维护性。 1. 静态类型检查&#xff08;S…...

Qt中设置QListWidget滑动条滚动速度

QListWidget继承QListView控件&#xff0c;Qt帮助文档中说 QAbstractItemView::ScrollPerPixel 和QAbstractItemView::ScrollPerItem分别可以实现按item滚动和像数点滚动&#xff0c;但是好像都没效果。还有就是说通过创建QScrollBar有用&#xff0c;但是也没效果。 亲测还是这…...

STM32的lorawan协议栈

LoRa 是LPWAN通信技术中的一种&#xff0c;是美国Semtech公司采用和推广的一种基于扩频技术的超远距离无线传输方案。这一方案改变了以往关于传输距离与功耗的折衷考虑方式为用户提供一种简单的能实现远距离、长电池寿命、大容量的系统&#xff0c;进而扩展传感网络。目前&…...

IC芯片 trustzone学习

搭建Airplay TA环境需要在IC的TrustZone中进行。TrustZone是一种安全技术&#xff0c;用于隔离安全和非安全环境&#xff0c;并保护敏感文件。在TrustZone中&#xff0c;我们需要编写一个叫做TA&#xff08;Trusted Application&#xff09;的应用程序来控制这些私密文档。 &am…...

Day19-异步请求-axios文件上传

Day19-异步请求 什么是同步请求当前浏览器刷新或者改变浏览器地址栏地址才能发送请求,这种请求称为同步请求 什么是异步请求当我们发送请求时,浏览器不会刷新,浏览器地址栏也不会变化,这种请求称为异步请求异步请求用到的前端技术: ajax 或 axios一 封装Ajax /*** 编写ajax函…...

qq企业邮箱 wordpress/医院营销策略的具体方法

关注“心仪脑”查看更多脑科学知识的分 关键词&#xff1a;干货分享 本期推文是 Public Neuroscience Dataset 系列主题的第五期内容。这期推文小编与大家分享TMS-EEG公开数据集。 &#xff08;版权所有©F.Farzan&#xff09; 经颅磁刺激&#xff08;Transcranial Magn…...

做一的同志小说网站有哪些/经典软文文案

挂载虚拟机报错连接超时&#xff1a; ~ # mount -t nfs -o nolock 10.10.8.171:/home/ytj/hi3516/nfs /mnt/nfs mount: mounting 10.10.8.171:/home/ytj/hi3516/nfs on /mnt/nfs failed: Connection timed out原因是虚拟机重启了&#xff0c;需要重新连接&#xff0c;点击虚拟…...

青岛正规的网站建设公司/seogw

原因很简单&#xff1a;win7,win8,WIN10自带了.net framework 4.6&#xff0c;版本比framework 4.5新了一点。而CAD2015的语言包(AutoCAD 2015 Language Pack)在安装中只能识别net framework 4.5&#xff0c;所以安装失败。CAD2015主程序没有问题&#xff0c;AutoCAD官方安装包…...

石家庄网站建设开发/seo优化教程下载

防蓝光危险评估结果是RG0的台灯随着人们对视力保护的重视&#xff0c;LED台灯市场快速发展和扩张&#xff0c;从而使大量的低价劣质台灯充斥市场&#xff0c;引起了大家对蓝光的恐惧。其实不必恐惧蓝光&#xff0c;而是注意LED台灯蓝光的量。下面&#xff0c;我们就谈谈蓝光的危…...

哪里找做网站的公司/活动推广软文

1 饼状图 import mx.collections.ArrayCollection; //绑定需要显示的数据 [Bindable] //设定要显示的数据 private var modelData:ArrayCollection new ArrayCollection( [ { Year: "2010年世界杯", Count: 4 }, { Year: "2014年世界杯", Count: 10 }, { …...

中国招标网官方网站/企业网络营销策划方案

/** Created by SharpDevelop. * User: noo * Date: 2009-8-16 * Time: 14:50 * * 抽象类 */usingSystem ;abstractclassAA//等同于 internal abstract class A&#xff0c;类只能在当前项目中访问&#xff0c;不能实例化&#xff08;无构造函数&#xff09;&#xff0c…...