JVM 类加载机制2

  • 扩展类加载器(Extension ClassLoader),该类加载器是由 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现,负责将 <JRE_HOME>/lib/ext 或者被 java.ext.dir 系统变量所指定路径中的所有类库加载到内存中,例如swing系列、内置的js引擎、xml解析器等以javax开头的扩展类库都是由扩展类加载器加载,开发者可以直接使用扩展类加载器。
  • 应用程序类加载器(Application ClassLoader),该类加载器是由 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现。由于这个类加载器是 ClassLoader 中的 getSystemClassLoader() 方法的返回值,因此也被称为系统类加载器。它负责加载用户类路径(ClassPath)上所指定的类库,比如:我们自己编写的自定义类或第三方jar包。开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。
public class ClassLoaderTest {public static void main(String[] args) {// (启动类)系统类加载器:ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();System.out.println(systemClassLoader); //sun.misc.Launcher$AppClassLoader@73d16e93//扩展类加载器:ClassLoader extendClassLoader = systemClassLoader.getParent();System.out.println(extendClassLoader); //sun.misc.Launcher$ExtClassLoader@15db9742// 引导类加载器:ClassLoader bootstrapClassLoader = extendClassLoader.getParent();System.out.println(bootstrapClassLoader); // null// 用户自定义的类默认用系统类加载器ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();System.out.println(classLoader); // sun.misc.Launcher$AppClassLoader@73d16e93}
}
5.3.什么情况下需要自定义类加载器?

1.隔离加载类。在某些框架内进行中间件与应用的模块之间进行隔离,把类加载到不同的环境。

2.修改类加载方式。

3.扩展加载源。比如:从数据库、网络、电视机顶盒进行类加载。

4.防止源码泄漏。比如:编译时字节码进行加密,需要通过自定义类加载器对字节码进行解密还原。

6.双亲委派模型

应用程序是由三种类加载器互相配合,从而实现类加载,除此之外还可以加入自己定义的类加载器。

类加载器之间的层次关系,称为双亲委派模型(Parents Delegation Model)。该模型要求除了顶层的启动类加载器外,其它的类加载器都要有自己的父类加载器。这里的父子关系一般通过组合关系(Composition)来实现,而不是继承关系(Inheritance)。

6.1.双亲委派工作机制

一个类加载器首先将类加载请求转发到父类加载器,只有当父类加载器无法完成时才尝试自己加载。

6.2双亲委派的作用
  1. 每个类只会加载一次,解决了各个类加载器加载基础类的统一问题(基础类库由上层的加载器进行加载);
  2. 防止恶意破坏的类加载,内存中不会出现多份同样的字节码的系统类,保证Java程序安全稳定运行。

例如:java.lang.Object 存放在 rt.jar 中,如果编写另外一个 java.lang.Object 并放到 ClassPath 中,程序可以编译通过。由于双亲委派模型的存在,所以在 rt.jar 中的 Object 比在 ClassPath 中的 Object 优先级更高,因为 rt.jar 中的 Object 使用的是启动类加载器,而 ClassPath中的 Object使用的是应用程序类加载器。rt.jar 中的 Object 优先级更高,那么程序中使用的所有的 Object 都是由启动类加载器所加载的 Object。

6.3双亲委派的实现源码

以下是抽象类 java.lang.ClassLoader 的代码片段,其中的 loadClass() 方法运行过程如下:先检查类是否已经加载过,如果没有则让父类加载器去加载。当父类加载器加载失败时抛出 ClassNotFoundException,此时尝试自己去加载。

public abstract class ClassLoader {// The parent class loader for delegationprivate final ClassLoader parent;public Class<?> loadClass(String name) throws ClassNotFoundException {return loadClass(name, false);}protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.c = findClass(name);}}if (resolve) {resolveClass(c);}return c;}}protected Class<?> findClass(String name) throws ClassNotFoundException {throw new ClassNotFoundException(name);}
}
6.4.SPI打破双亲委派

SPI(Service Provider Interface),是一种服务发现机制,它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。

如下图,SPI核心类定义在rt.jar中(例如:java.lang.Driver接口),所以java.lang.Driver接口本身是由启动类加载器加载,当调用java.lang.Driver接口的实现类时,启动类加载器是无法加载实现类的,这个时候就提供了线程上下文类加载器(Thread Context ClassLoader)加载实现类,ThreadContextClassLoader是可以通过java.lang.Thread#setContextClassLoader方法设置类加载器,这样就打破了双亲委派的类加载模式。

7.对象的创建过程

Step1:类加载检查

虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

Step2:分配内存

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。内存分配的查找方式有 “指针碰撞” 和 “空闲列表” 两种。

选择以上两种方式中的哪一种,取决于 Java 堆内存是否规整。而 Java 堆内存是否规整,取决于 GC 收集器的算法是"标记-清除",还是"标记-整理"。

Step3:初始化零值

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

Step4:设置对象头

初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。

Step5:执行 init 构造方法

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从Java 程序的视角来看,对象创建才刚开始,<init> 构造方法还没有执行,目前所有的字段都还为零。所以一般来说,执行 new 指令之后会接着执行 <init> 构造方法,把对象按照程序逻辑的意愿进行初始化,这样一个真正可用的对象才算完整创建出来。

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

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

相关文章

open-resty 服务安装kafka插件

从github下载 作者&#xff1a;程序那点事儿 日期&#xff1a;2023/11/16 22:01 lua-resty-kafka 插件安装 下载代码后直接解压 mkdir -p /usr/local/openresty/modules/ #创建一个目录&#xff0c;存放lua插件cd /usr/local/openresty/modules/ #进入目录rz -y #上传lua插件…

SOMEIP_ETS_136: SD_Option_Length_shorter_GT_0_as_specified_for_type

测试目的&#xff1a; 验证DUT能够处理一个UDP选项长度小于其类型所指定长度的SubscribeEventgroup消息&#xff0c;并以SubscribeEventgroupNAck作为响应或完全忽略该请求。 描述 本测试用例旨在确保DUT遵循SOME/IP协议&#xff0c;当接收到一个UDP选项长度小于其类型所指定…

WPS在表格中填写材料时,内容过多导致表格不换页,其余内容无法正常显示 以及 内容过多,导致表格换页——解决方法

一、现象 1&#xff0c;内容过多导致表格不换页&#xff0c;其余内容无法正常显示 2&#xff0c;内容过多&#xff0c;导致表格换页 二、解决方法 在表格内右击&#xff0c;选择表格属性 在菜单栏选择行&#xff0c;勾选允许跨页断行&#xff0c;点击确定即可 1&#xff0…

windows安装Redis以后配置远程访问

修改配置文件&#xff1a; 第一个地方&#xff1a; 第二个地方&#xff1a; 启动服务&#xff1a; redis-server .\redis.windows.conf 可能需要重启计算机 经过实测&#xff0c;这个配置文件也得改&#xff1a; 如果不想重启计算机&#xff0c;可以执行下面的命令重启…

代码随想录冲冲冲 Day56 图论Part8

117. 软件构建 这道题是使用拓扑排序的方法 看多个任务有优先级的情况下 怎么排序 对应到这道题就是文件排序 首先要记录每一个点的入度&#xff0c;当一个点的入度为0时&#xff0c;就说明这个点是顶点 然后记录每一个点向那些点相连 之后建立一个queue 寻找一个入度为0的…

基于quill2.0的富文本编辑器,Fluent Editor,支持表格,图片,表情等

官网&#xff1a;Fluent Editor | 基于 Quill 2.0 的富文本编辑器 安装 npm i opentiny/fluent-editor quill 使用案例 <template><div class"publish-form-container"><!-- TODO --><div ref"quillEditorRef" class"quill…

python的逻辑控制

python逻辑执行 python条件控制if嵌套循环语句内置函数range()Pass语句 python迭代器与生成器在python中创建一个迭代器生成器yield python条件控制 # 在python中&#xff0c;不使用括号将条件固定 if exp: # 条件满足则执行&#xff0c;后续语句不执行# 不使用{}将执行语句固…

Java框架学习(mybatis)(01)

简介&#xff1a;以本片记录在尚硅谷学习ssm-mybatis时遇到的小知识 详情移步&#xff1a;想参考的朋友建议全部打开相互配合学习&#xff01; 官方文档&#xff1a; MyBatis中文网https://mybatis.net.cn/index.html 学习视频&#xff1a; 067-mybatis-介绍和对比_哔哩哔…

《向量数据库指南》——Zilliz迁移服务:一键解锁跨平台数据迁移新纪元

在数据驱动的时代背景下&#xff0c;非结构化数据的处理与迁移已成为企业数字化转型中不可或缺的一环。随着向量数据库技术的飞速发展&#xff0c;尤其是像Milvus这样的高性能向量数据库系统的广泛应用&#xff0c;如何高效、安全、准确地实现数据在不同系统间的迁移&#xff0…

Arthas mc(Memory Compiler/内存编译器 )

文章目录 二、命令列表2.2 class/classloader相关命令2.2.2 mc &#xff08;Memory Compiler/内存编译器 &#xff09;举例1&#xff1a;可以通过-d命令指定输出目录&#xff1a;mc -d /temporary/tmp /temporary/tmp/AccountController.java举例2&#xff1a;通过--classLoade…

书生大模型实战营学习[7] InternLM + LlamaIndex RAG 实践

环境配置 选择30%A100做本次任务 conda create -n llamaindex python3.10 conda activate llamaindex conda install pytorch2.0.1 torchvision0.15.2 torchaudio2.0.2 pytorch-cuda11.7 -c pytorch -c nvidia pip install einops pip install protobuf安装Llamaindex cond…

2024年9月27日历史上的今天大事件早读

1540年09月27日罗马教皇正式批准耶稣会 1605年09月27日吉尔霍尔姆战役爆发 1825年09月27日世界第一条铁路在英国正式通车 1840年09月27日美国海军战略思想家马汉出生 1858年09月27日天地会起义&#xff0c;建立大成国 1910年09月27日橡胶股灾亡国录 1913年09月27日孙中山…

隆道供应商四大类服务升级全面速览!

隆道供应商服务升级&#xff0c;全流程在线业务协同场景&#xff0c;支持系统性交易协同服务和企业营销&#xff0c;通过持续深入洞察供应商的核心需求&#xff0c;对营销类、协同类、风控类及数据类四大关键服务进行了全面升级。推出一系列创新应用&#xff0c;致力于帮助供应…

项目启动错误

说明&#xff1a;记录一次项目启动&#xff0c;报数据库访问错误&#xff0c;如下&#xff1a; 错误信息&#xff1a;Invalid default&#xff1a;public abstract java.lang.Class tk.mybatis.spring.annotation.MapperScan.fatoryBean() 解决 没有引入mybatis依赖&#xff…

AlphaFold3 | 详解 AlphaFold3 的模型结构及其在不同类型的预测实验中的表现

Jumper 本文将介绍 24 年 5 月发布的 Alaphafold3&#xff0c;其以“使用 AlphaFold 3 进行生物分子相互作用的精确结构预测”为标题发表在《nature》上&#xff0c;通讯作者为 Jumper。 Jumper 具有物理、化学、生物和计算方面的丰富背景。Jumper 本科学的是物理和数学&#…

Python中的数据处理与分析:从基础到高级

在数据科学和数据分析领域&#xff0c;Python凭借其丰富的库和强大的生态系统&#xff0c;成为了最受欢迎的语言之一。本文将从基础到高级&#xff0c;详细介绍如何使用Python进行数据处理和分析&#xff0c;涵盖数据清洗、数据转换、数据可视化等多个方面。 1. 数据导入与导出…

网络安全专业,在校大学生如何赚外快,实现财富自由?零基础入门到精通,收藏这一篇就够了

如今&#xff0c;计算机行业内卷严重&#xff0c;我们不找点赚外快的路子这么行呢&#xff1f; 今天就来说说网络安全专业平时都怎么赚外快。 一、安全众测 国内有很多成熟的src众测平台&#xff0c;如漏洞盒子、火线众测、补天、CNVD、漏洞银行等。一些大厂也有自己的src&a…

下载配置Android Studio(2024年9月)

安装JAVA JDK 下载安装包 Java网站官网 Java Downloads | Oracle 我下载的是JDK Development Kit 17.0.12 downloads Windows x64 MSI Installer。 下载后打开文件&#xff0c;一路NEXT闭眼安装。 配置环境变量 设置-系统-系统高级设置-环境变量 1.新建一个系统环境变量&…

【Linux系统编程】第二十四弹---从零到一:掌握进程替换的奥秘

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、进程程序替换 1.1、替换原理 1.2、替换函数 1.3、函数解释 1.4、命名理解 1.5、代码演示 1.5.1、execl调用举例 1.5…

Dina: 1.0.1靶场

下载链接&#xff1a;https://download.vulnhub.com/dina/Dina-1-0-1.ova 一、信息收集 靶机界面 扫描主机ip arp-scan -l 扫描端口 nmap -p- -A 192.168.137.129 扫描目录 dirb http://192.168.137.129/ 打开网站 没有太多有用信息&#xff0c;点击提交后会有个目录 依旧…