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

JVM:类加载器

文章目录

  • 一、什么是类加载器
  • 二、类加载器的应用场景
  • 三、类加载器的分类
    • 1、分类
    • 2、启动类加载器
    • 3、Java中的默认类加载器
      • (1)扩展类加载器
      • (2)应用程序类加载器
      • (3)arthas中类加载器相关的功能
  • 四、双亲委派机制
    • 1、介绍
    • 2、双亲委派的作用
      • (1)保证类加载的安全性
      • (2)避免重复加载
    • 3、Java中如何使用代码方式去主动加载一个类
    • 4、类加载器
      • (1)介绍
      • (2)arthas中类加载器相关的功能
  • 五、打破双亲委派机制
    • 1、打破双亲委派机制的三种方式
      • (1)自定义类加载器
      • (2)线程上下文类加载器
      • (3)Osgi框架的类加载器
  • 六、JDK9之后的类加载器

一、什么是类加载器

类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。类加载器只参与加载过程总的字节码获取并加载到内存这一部分。
在这里插入图片描述

二、类加载器的应用场景

在这里插入图片描述

三、类加载器的分类

1、分类

  • 类加载器分为两类,一类是Java代码中实现的,一类是Java虚拟机底层源码实现的。
    在这里插入图片描述
  • 类加载器的设计JDK8和8之后的版本差别较大,JDK8及之前的版本默认的类加载器有如下几种:
    在这里插入图片描述
  • 类加载器的详细信息可以通过Arthas classloader命令查看:classloader - 查看classloader的继承树,urls,类加载信息,使用classloader去getResource。
    在这里插入图片描述

2、启动类加载器

  • 启动类加载器(Boostrap ClassLoader)是由HotSpot虚拟机提供的、使用C ++编写的类加载器。
  • 默认加载Java安装目录/jre/lib下的类文件,比如rt.jar,tool.jar,resource.jar等。
    在这里插入图片描述
    通过启动类加载器去加载用户jar包
  • 放入jre/lib下进行扩展:不推荐,尽可能不要去更改JDK安装目录中的内容,会出现即使放进去由于文件名不匹配的问题也不会正常被加载。
  • 使用参数进行扩展:推荐,使用-Xbootclasspath/a:jar包目录/jar包名,进行扩展。

3、Java中的默认类加载器

  • 扩展类加载器和应用程序类加载器都是JDK中提供的、使用Java编写的类加载器。
  • 他们的源码都位于sun.misc.Launcher中,是一个静态内部类。继承自URLClassLoader。具备通过目录或者指定jar包将字节码文件加载到内存中。
    在这里插入图片描述

(1)扩展类加载器

  • 扩展类加载器(Extension Class Loader)是JDK中提供的、使用Java编写的类加载器。
  • 默认加载Java安装目录/jre/lib/ext下的类文件。
    在这里插入图片描述

通过扩展类加载器去加载用户jar包

  • 放入/jre/lib/ext下进行扩展:不推荐,尽可能不要去更改JDK安装目录中的内容。
  • 使用参数进行扩展:推荐,使用**-Djava.ext.dirs=jar包目录**,进行扩展,这种方式会覆盖原始目录,可以用;(windows)、:(macos/linux)追加原始目录。

(2)应用程序类加载器

加载classpath下的类文件。

(3)arthas中类加载器相关的功能

类加载器的加载路径可以通过classloader -c hash值查看:
在这里插入图片描述

四、双亲委派机制

1、介绍

由于Java虚拟机中有多个类加载器,双亲委派机制的核心是解决一个类到底由谁加载的问题。双亲委派机制指的是:当一个类加载器收到加载类的任务时,会自底向上查找是否加载过,再由顶向下进行加载。向上查找如果已经加载过,就直接返回Class对象,加载过程结束。这样就能避免一个类重复加载。如果所有的父类加载器都无法加载该类,则由当前类加载器自己尝试加载。所以看上去是指顶向下尝试加载。
在这里插入图片描述

2、双亲委派的作用

(1)保证类加载的安全性

通过双亲委派机制避免恶意代码替换JDK中的核心类库,比如java.lang.String,确保核心类库的完整性和安全性。

(2)避免重复加载

双亲委派机制可以避免同一个类被多次加载。

3、Java中如何使用代码方式去主动加载一个类

  • 使用Class.forName方法,使用当前类的类加载器去加载指定的类。
    public static Class<?> forName(String className)throws ClassNotFoundException {Class<?> caller = Reflection.getCallerClass();return forName0(className, true, ClassLoader.getClassLoader(caller), caller);}private static native Class<?> forName0(String name, boolean initialize,ClassLoader loader,Class<?> caller)throws ClassNotFoundException;
  • 获取到类加载器,通过类加载器的loadClass方法指定某个类加载器加载。

4、类加载器

(1)介绍

每个Java实现的类加载器中保存了一个成员变量叫“父”类加载器,可以理解为他的上级,不是继承关系。
在这里插入图片描述

  • 应用程序类加载器的parent父类加载器时扩展类加载器,而扩展类加载器parent是空,但是在逻辑上,扩展类加载器依然会把启动类加载器当成父类加载器处理。
  • 启动类加载器使用C++编写,没有父类加载器。
    在这里插入图片描述
    下面体现了启动类加载器、扩展类加载器和应用程序类加载器的层级关系。
    在这里插入图片描述

(2)arthas中类加载器相关的功能

类加载器的父子关系可以通过classloader -t查看
在这里插入图片描述

五、打破双亲委派机制

1、打破双亲委派机制的三种方式

(1)自定义类加载器

  • 自定义类加载器并且重写loadClass方法,就可以将双亲委派机制的代码去除。
  • Tomcat通过这种方式实现应用之间的类隔离。
    • Tomact使用了自定义类加载器来实现应用之间类的隔离。每个应用会有一个独立的类加载器加载对应的类。
      在这里插入图片描述
  • 先来分析ClassLoader的原理,ClassLoader中包含了4个核心方法。
  • 双亲委派机制的核心代码位于loadClass方法中。
    在这里插入图片描述
  • 阅读双亲委派机制的核心代码,分析如何通过自定义的类加载器打破双亲委派机制。
  • 打破双亲委派机制就是将下边的一段代码重新实现。
    在这里插入图片描述

自定义类加载器默认的父类加载器

  • 以JDK8为例,ClassLoader类中提供了构造方法设置parent的内容。
    在这里插入图片描述

  • 这个构造方法由另外一个构造方法调用,其中父类加载器由getSystemClassLoader方法设置,该方法返回的是AppClassLoader。
    在这里插入图片描述

两个自定义类加载器加载相同限定名类不会冲突

  • 在同一个Java虚拟机中,只有相同了加载器+相同的类限定名才会被认为是同一个类。
  • 在Arthas中使用sc -d 类名的方式查看具体的情况。

(2)线程上下文类加载器

利用上下文类加载器加载类,比如JDBC和JNDI。

(3)Osgi框架的类加载器

历史上Osgi框架实现了一套新的类加载机制,允许同级之间委托进行类的加载。

六、JDK9之后的类加载器

  • 由于JDK9引入了module的概念,类加载器在设计上发生了很多的变化。
    在这里插入图片描述
    • 启动类加载器使用Java编写,位于jdk.internal.loader.ClassLoaders类中。java中的BootClassLoader继承自BuiltinClassLoader实现从某块中找到要加载的字节码资源文件。启动类加载器依然无法通过java代码获取到,返回的仍然是null,保持了统一。
      在这里插入图片描述
  • 扩展类加载器被替换成了平台类加载器(Platform Class Loader)。平台类加载器遵循模块化方式加载字节码文件,所以继承关系从URLClassLoader变成了BuiltinClasLoader,BuiltinClasLoader实现了从模块中加载字节码文件。平台类加载器的存在更多的是为了与老版本的设计方案兼容,自身没有特殊的逻辑。
    在这里插入图片描述

相关文章:

JVM:类加载器

文章目录 一、什么是类加载器二、类加载器的应用场景三、类加载器的分类1、分类2、启动类加载器3、Java中的默认类加载器&#xff08;1&#xff09;扩展类加载器&#xff08;2&#xff09;应用程序类加载器&#xff08;3&#xff09;arthas中类加载器相关的功能 四、双亲委派机…...

支持向量机 (support vector machine,SVM)

支持向量机 &#xff08;support vector machine&#xff0c;SVM&#xff09; flyfish 支持向量机是一种用于分类和回归的机器学习模型。在分类任务中&#xff0c;SVM试图找到一个最佳的分隔超平面&#xff0c;使得不同类别的数据点在空间中被尽可能宽的间隔分开。 超平面方…...

宝塔面板以www用户运行composer

方式一 执行命令时指定www用户 sudo -u www composer update方式二 在网站配置中的composer选项卡中选择配置运行...

昇思25天打卡营-mindspore-ML- Day24-基于 MindSpore 实现 BERT 对话情绪识别

学习笔记&#xff1a;基于MindSpore实现BERT对话情绪识别 算法原理 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是由Google于2018年开发的一种预训练语言表示模型。BERT的核心原理是通过在大量文本上预训练深度双向表示&#xff0…...

【精品资料】模块化数据中心解决方案(33页PPT)

引言&#xff1a;模块化数据中心解决方案是一种创新的数据中心设计和部署策略&#xff0c;旨在提高数据中心的灵活性、可扩展性和效率。这种方案通过将数据中心的基础设施、计算、存储和网络资源封装到标准化的模块中&#xff0c;实现了快速部署、易于管理和高效运维的目标 方案…...

N6 word2vec文本分类

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊# 前言 前言 上周学习了训练word2vec模型&#xff0c;这周进行相关实战 1. 导入所需库和设备配置 import torch import torch.nn as nn import torchvision …...

excel、word、ppt 下载安装步骤整理

请按照我的步骤开始操作&#xff0c;注意以下截图红框标记处&#xff08;往往都是需要点击的地方&#xff09; 第一步&#xff1a;下载 首先进入office下载网址&#xff1a; otp.landian.vip 然后点击下载 拉到下方 下载站点&#xff08;这里根据自己的需要选择下载&#x…...

【python学习】标准库之日期和时间库定义、功能、使用场景和示例

引言 datetime模块最初是由 Alex Martelli 在 Python 2.3 版本引入的&#xff0c;目的是为了解决之前版本中处理日期和时间时存在的限制和不便 在datetime模块出现之前&#xff0c;Python 主要使用time模块来处理时间相关的功能&#xff0c;但 time模块主要基于 Unix 纪元时间&…...

Android --- Kotlin学习之路:基础语法学习笔记

------>可读可写变量 var name: String "Hello World";------>只读变量 val name: String "Hello World"------>类型推断 val name: String "Hello World" 可以写成 val name "Hello World"------>基本数据类型 1…...

嵌入式智能手表项目实现分享

简介 这是一个基于STM32F411CUE6和FreeRTOS和LVGL的低成本的超多功能的STM32智能手表~ 推荐 如果觉得这个手表的硬件难做,又想学习相关的东西,可以试下这个新出的开发板,功能和例程demo更多!FriPi炸鸡派STM32F411开发板: 【STM32开发板】 FryPi炸鸡派 - 嘉立创EDA开源硬件平…...

`nmap`模块是一个用于与Nmap安全扫描器交互的库

在Python中&#xff0c;nmap模块是一个用于与Nmap安全扫描器交互的库。Nmap&#xff08;Network Mapper&#xff09;是一个开源工具&#xff0c;用于发现网络上的设备和服务。虽然Python的nmap模块可能不是官方的Nmap库&#xff08;因为Nmap本身是用C/C编写的&#xff09;&…...

JVM系列 | 对象的创建与存储

JVM系列 | 对象的生命周期1 对象的创建与存储 文章目录 前言对象的创建过程内存空间的分配方式方式1 | 指针碰撞方式2 | 空闲列表 线程安全问题 | 避免空间冲突的方式方式1 | 同步处理&#xff08;加锁)方式2 | 本地线程分配缓存 对象的内存布局Part1 | 对象头Mark Word类型指针…...

【JavaScript 算法】快速排序:高效的排序算法

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、算法原理二、算法实现三、应用场景四、优化与扩展五、总结 快速排序&#xff08;Quick Sort&#xff09;是一种高效的排序算法&#xff0c;通过分治法将数组分为较小的子数组&#xff0c;递归地排序子数组。快速排序通常…...

Excel如何才能忽略隐藏行进行复制粘贴?

你有没有遇到这样的情况&#xff1a;数据很多&#xff0c;将一些数据隐藏后&#xff0c;进行复制粘贴&#xff0c;结果发现粘贴后的内容仍然将整个数据都显示出来了&#xff01;那么&#xff0c;Excel如何才能忽略隐藏行进行复制粘贴&#xff1f; 打开你的Excel表格 Excel如何…...

行人越界检测 越线 越界区域 多边形IOU越界判断

行人越界判断 越界判断方式&#xff1a;&#xff08;1&#xff09;bbox中心点越界&#xff08;或自定义&#xff09;&#xff08;2&#xff09;交并比IoU判断 越界类型&#xff1a;&#xff08;1&#xff09;越线 &#xff08;2&#xff09;越界区域 1.越线判断 bbox中心点xc、…...

「UCD」浅谈蓝湖Figma交互设计对齐

在现代数字产品的设计和开发过程中,选择合适的工具对于提高团队效率和保证产品质量至关重要。本文将从开发和设计两个不同的角度,探讨蓝湖和Figma两款流行工具的优势与不足,并提出结论和建议。 开发研发视角:蓝湖 优点: 清晰的设计规范:蓝湖为开发工程师提供了清晰的设计…...

VUE3 播放RTSP实时、回放(NVR录像机)视频流(使用WebRTC)

1、下载webrtc-streamer&#xff0c;下载的最新window版本 Releases mpromonet/webrtc-streamer GitHub 2、解压下载包 3、webrtc-streamer.exe启动服务 &#xff08;注意&#xff1a;这里可以通过当前文件夹下用cmd命令webrtc-streamer.exe -o这样占用cpu会很少&#xff0c…...

[PaddlePaddle飞桨] PaddleOCR-光学字符识别-小模型部署

PaddleOCR的GitHub项目地址 推荐环境&#xff1a; PaddlePaddle > 2.1.2 Python > 3.7 CUDA > 10.1 CUDNN > 7.6pip下载指令&#xff1a; python -m pip install paddlepaddle-gpu2.5.1 -i https://pypi.tuna.tsinghua.edu.cn/simple pip install paddleocr2.7…...

Python应用开发——30天学习Streamlit Python包进行APP的构建(15):优化性能并为应用程序添加状态

Caching and state 优化性能并为应用程序添加状态! Caching 缓存 Streamlit 为数据和全局资源提供了强大的缓存原语。即使从网络加载数据、处理大型数据集或执行昂贵的计算,它们也能让您的应用程序保持高性能。 本页仅包含有关 st.cache_data API 的信息。如需深入了解缓…...

python实现openssl的EVP_BytesToKey及AES_256_CBC加解密算法

python实现openssl EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), NULL, pass, passlen, 1, key, iv); 并实现AES 256 CBC加解密. # encoding:utf-8import base64 from Crypto.Cipher import AES from Crypto import Random from hashlib import md5def EVP_BytesToKey(passw…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)

+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...