JVM 虚拟机 类的加载器分类与测试详解

news2024/10/7 12:22:34

Java全能学习+面试指南:https://javaxiaobear.cn

1、类加载器的分类说明

JVM支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader)自定义类加载器(User-Defined ClassLoader)。

从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范却没有这么定义,而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器。

无论类加载器的类型如何划分,在程序中我们最常见的类加载器结构主要是如下情况:

image-20231129180714022

2、子父类加载器的关系?

除了顶层的启动类加载器外,其余的类加载器都应当有自己的“父类”加载器。

不同类加载器看似是继承(Inheritance)关系,实际上是包含关系。在下层加载器中,包含着上层加载器的引用。

class ClassLoader{
     ClassLoader parent; //父类加载器
 
     public ClassLoader(ClassLoader parent){ 
          this.parent = parent;
     }
}
class ParentClassLoader extends ClassLoader{
     public ParentClassLoader(ClassLoader parent){
          super(parent);
     }
}
class ChildClassLoader extends ClassLoader{
     public ChildClassLoader(ClassLoader parent){ //parent = new ParentClassLoader();
          super(parent);
     }
}

3、具体类的加载器介绍

1、引导类加载器

启动类加载器(引导类加载器,Bootstrap ClassLoader)

  • 这个类加载使用C/C++语言实现的,嵌套在JVM内部。
  • 它用来加载Java的核心库(JAVA_HOME/jre/lib/rt.jar或sun.boot.class.path路径下的内容)。用于提供JVM自身需要的类。
  • 并不继承自java.lang.ClassLoader,没有父加载器。
  • 出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类
  • 加载扩展类和应用程序类加载器,并指定为他们的父类加载器。
image-20231129181008798

使用-XX:+TraceClassLoading参数得到。

启动类加载器使用C++编写的? Yes!

  • C/C++:指针函数&函数指针、C++支持多继承
  • Java:由C++演变而来,(C++)–版,单继承

2、扩展类加载器

  • Java语言编写,由sun.misc.Launcher$ExtClassLoader实现。
  • 继承于ClassLoader类
  • 父类加载器为启动类加载器
  • 从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录下加载类库。如果用户创建的JAR放在此目录下,也会自动由扩展类加载器加载。

image-20231129181122042

3、系统类加载器

应用程序类加载器(系统类加载器,AppClassLoader)

  • java语言编写,由sun.misc.Launcher$AppClassLoader实现
  • 继承于ClassLoader类
  • 父类加载器为扩展类加载器
  • 它负责加载环境变量classpath或系统属性 java.class.path 指定路径下的类库
  • 应用程序中的类加载器默认是系统类加载器。
  • 它是用户自定义类加载器的默认父加载器
  • 通过ClassLoader的getSystemClassLoader()方法可以获取到该类加载器

4、用户自定义类加载器

  • 在Java的日常应用程序开发中,类的加载几乎是由上述3种类加载器相互配合执行的。在必要时,我们还可以自定义类加载器,来定制类的加载方式。
  • 体现Java语言强大生命力和巨大魅力的关键因素之一便是,Java开发者可以自定义类加载器来实现类库的动态加载,加载源可以是本地的JAR包,也可以是网络上的远程资源。
  • 通过类加载器可以实现非常绝妙的插件机制,这方面的实际应用案例举不胜举。例如,著名的OSGI组件框架,再如Eclipse的插件机制。类加载器为应用程序提供了一种动态增加新功能的机制,这种机制无须重新打包发布应用程序就能实现。
  • 同时,自定义加载器能够实现应用隔离,例如 Tomcat,Spring等中间件和组件框架都在内部实现了自定义的加载器,并通过自定义加载器隔离不同的组件模块。这种机制比C/C++程序要好太多,想不修改C/C++程序就能为其新增功能,几乎是不可能的,仅仅一个兼容性便能阻挡住所有美好的设想。
  • 所有用户自定义类加载器通常需要继承于抽象类java.lang.ClassLoader。

5、测试不同的类加载器

每个Class对象都会包含一个定义它的ClassLoader的一个引用。

获取ClassLoader的途径

  • 获得当前类的ClassLoader:clazz.getClassLoader()
  • 获得当前线程上下文的ClassLoader:Thread.currentThread().getContextClassLoader()
  • 获得系统的ClassLoader:ClassLoader.getSystemClassLoader()

说明:
站在程序的角度看,引导类加载器与另外两种类加载器(系统类加载器和扩展类加载器)并不是同一个层次意义上的加载器,引导类加载器是使用C++语言编写而成的,而另外两种类加载器则是使用Java语言编写而成的。由于引导类加载器压根儿就不是一个Java类,因此在Java程序中只能打印出空值。

数组类的Class对象,不是由类加载器去创建的,而是在Java运行期JVM根据需要自动创建的。对于数组类的类加载器来说,是通过Class.getClassLoader()返回的,与数组当中元素类型的类加载器是一样的;如果数组当中的元素类型是基本数据类型,数组类是没有类加载器的。

String[] strArr = new String[6];
System.out.println(strArr.getClass().getClassLoader());
// 运行结果:null

ClassLoaderTest[] test = new ClassLoaderTest[1];
System.out.println(test.getClass().getClassLoader());
// 运行结果:sun.misc.Launcher$AppClassLoader@18b4aac2

int[] ints = new int[2];
System.out.println(ints.getClass().getClassLoader());
// 运行结果:null

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1296916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

webpack该如何打包

1.我们先创建一个空的大文件夹 2.打开该文件夹的终端 输入npm init -y 2.1.打开该文件夹的终端 2.2在该终端运行 npm init -y 3.安装webpack 3.1打开webpack网址 点击“中文文档” 3.2点击“指南”在点击“起步” 3.3复制基本安装图片画线的代码 4.在一开始的文件夹下在创建一…

营收增速持续放缓,博通CEO期待AI崛起救场 | 百能云芯

博通作为苹果等大型科技公司的芯片供应商,于周四发布了财报。尽管截至10月29日的第四季度营收增长了4%至93亿美元,符合市场预期,但增速已经降至2020年以来的最低水平。 由于企业客户和电信供应商在控制支出方面的谨慎态度,博通的销…

C 语言 变量

变量初始值 全局变量:初始值是 0 局部变量:初始值是 随机的 类型限定符 通常不需要显式使用 register 关键字来优化变量的存储和访问。 关键字 _Complex和_Imaginary分别用于表示复数和虚数(二者皆是数学概念) 变量的声明和定义 c…

【小白专用】MySQL创建数据库和创建数据表

1.在Windows开始搜索输入Mysql,并选择第一个打开。 2.输入安装时的密码 3.说明安装成功。 二、创建数据库 1. 连接 MySQL 输入 mysql -u root -p 命令,回车,然后输入 MySQL 的密码(不要忘记了密码),再回车,就连接上 MySQL 了。 …

Vue3选项式-基础部分篇

Vue3选项式风格-基础部分篇 简介模板语法文本插值原始HTMLAttribute 绑定使用 JavaScript 表达式调用函数全局组件调用内置指令动态参数注意事项 data()data()深度响应 methods有状态的methods(防抖) DOM更新时机计算属性class和style绑定条件渲染列表渲染数组变换侦听事件处理…

全网最新最全【Kali Linux】 渗透测试技术大全

利矛出击:Kali Linux 渗透测试大法 在网络攻防实践中,系统的防御措施可以称为“盾”,而渗透测试则是“矛”。二者同等重要,因为“矛”可以试探出“盾”有多坚固,并且及时发现问题,修补漏洞,提升…

k8s之镜像拉取时使用secret

k8s之secret使用 一、说明二、secret使用2.1 secret类型2.2 创建secret2.3 配置secret 一、说明 从公司搭建的网站镜像仓库,使用k8s部署服务时拉取镜像失败,显示未授权: 需要在拉取镜像时添加认证信息. 关于secret信息,参考: https://www.…

[英语学习][10][Word Power Made Easy]的精读与翻译优化

[序言] 下面这段话, 译者翻译没有太大问题, 就是某些单词上, 跟他理解得不一样. 另外还有一个关键的定语从句, 我认为译者理解不到位, 导致翻译不够通顺. [英文学习的目标] 提升自身的英语水平, 对日后编程技能的提升有很大帮助. 希望大家这次能学到东西, 同时加入我的社区讨…

修改正点原子综合实验的NES模拟器按键控制加横屏

​​​​​​​ 开发板:stm32f407探索者开发板V2 屏幕是4.3寸-800-480-MCU屏 手头没有V3开发板,只有V2,所以没法测试 所以只讲修改哪里,请自行修改 先改手柄部分,把手柄改成按键 找到左边的nes文件夹中的nes_mai…

matlab RGB三元组和十六进制的转换

matlab画柱状图改颜色的时候,用三元组的形式,范围是[0,1] 我们获得了十六进制 到网站转换为[0,255] https://c.runoob.com/front-end/55/ 然后将得到的值/255 输入matlab就可以了

VS2009和VS2022的错误列表可复制粘贴为表格

在VS2019或VS2022中,可看到如下错误列表: 如果复制这两行错误信息: 然后把它粘贴到word文件,就可以看到以下表格: 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0020 未定义标识符 "dd"…

Docker 部署 2FAuth 服务

拉取最新版本的 2FAuth 镜像: $ sudo docker pull 2fauth/2fauth:latest在本地预先创建好 2fauth 目录, 用于映射 2FAuth 容器内的 /2fauth 目录。 使用以下命令, 在 前台 运行 2FAuth 容器: $ sudo docker run -it --rm --name 2fauth -p 10085:8000/tcp -v /ho…

从简单到入门,一文掌握jvm底层知识文集。

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…

Qt基础-组件的添加、删除或更新

本文介绍如何在Qt中组件的添加、删除或更新。 概述 有时安装完qt后发现当前的组件需要进一步调整,这时就需要进一步操作安装的文件。 QT的组件管理软件并没有在开始菜单或者桌面添加快捷方式(5.9版本),也没有在代码编辑界面设置相关的选项,藏的比较深。 操作步骤 找到…

【工程实践】使用modelscope下载大模型文件

前言 Modelscope(魔搭社区)是阿里达摩院的一款开源模型平台,里面提供了很多的热门模型供使用体验,其中的模型文件可以通过git clone 快速下载。并且为模型提供了Notebook的快速开发体验,使用阿里云服务,不需…

arm平台编译so文件回顾

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、几个点二、回顾过程 1.上来就执行Makefile2.编译第三方开源库.a文件 2.1 build.sh脚本2.2 Makefile3.最终编译三、其它知识点总结 前言 提示:这…

一天一个设计模式---生成器模式

概念 生成器模式(Builder Pattern)是一种创建型设计模式,用于构建复杂对象。它允许您逐步构造一个对象,将构建过程与最终对象的表示分离开来。这种模式通常用于创建复杂的对象,这些对象可能有多个部分组成&#xff0c…

MongoDB的插入文档、更新文档语句

本文主要介绍MongoDB的插入文档、更新文档语句。 目录 MongoDB插入文档MongoDB更新文档 MongoDB插入文档 在MongoDB中,可以通过使用insertOne或insertMany方法向集合中插入文档。 insertOne方法可以插入一个文档,例如: db.collection.inse…

条码生成器与Zint使用

文章目录 目的条形码zint支持条形码种类下载编译qt pro配置code保存条形码目的 1: 了解条形码数据理论知识 2: 了解zint第三方库相关, 如何编译引用到项目中 条形码 条形码(Barcode)一维码 和二维码(QR code)都是用于存储信息的图形化表示方式,通常应用于商品标识、库…

LeetCode(52)最小栈【栈】【中等】

目录 1.题目2.答案3.提交结果截图 链接: 最小栈 1.题目 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void…