【JVM基础篇】类加载器分类介绍

文章目录

    • 类加载器
      • 什么是类加载器
      • 类加载器的作用是什么
      • 应用场景
      • 类加载器的分类
        • 启动类加载器
          • 用户扩展基础jar包
        • 扩展类加载器和应用程序类加载器
        • 扩展类加载器
          • 通过扩展类加载器去加载用户jar包:
        • 应用程序加载器
      • Arthas中类加载器相关功能
    • 文章说明

类加载器

什么是类加载器

类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术

在这里插入图片描述

在这里插入图片描述

类加载器会通过二进制流的方式获取到字节码文件的内容,接下来将获取到的数据交给Java虚拟机,虚拟机会在方法区和堆上生成对应的对象保存字节码信息。

类加载器的作用是什么

  • **类加载器(ClassLoader)负责在类加载过程中的字节码获取并加载到内存这一部分,**通过加载字节码数据放入内存转换成byte[],接下来调用虚拟机底层方法将byte[]转换成方法区和堆中的数据。

应用场景

  • 企业级应用
    • SPI机制
    • 类的热部署
    • Tomcat类的隔离
  • 大量的面试题
    • 什么是类的双亲委派机制
    • 打破类的双亲委派机制
    • 自定义类加载器
  • 解决线上问题
    • 使用Arthas不停机解决线上故障

类加载器的分类

类加载器分为两类,一类是Java代码中实现的,一类是Java虚拟机底层源码实现的。

  • 虚拟机底层实现:源代码位于Java虚拟机的源码中,实现语言与虚拟机底层语言一致,比如Hotspot使用C++。主要目的是保证Java程序运行的基础类被正确地加载,比如java.lang.String,Java虚拟机需要确保其可靠性。
  • JDK中默认提供或者自定义:JDK中默认提供了多种处理不同渠道的类加载器,程序员也可以自己根据需求使用Java语言定制。所有Java中实现的类加载器都需要继承ClassLoader这个抽象类。

在这里插入图片描述

可以查看所有类加载器,即ClassLoader的子类

在这里插入图片描述

类加载器的设计,JDK8和8之后的版本差别较大。首先来看JDK8及之前的版本,这些版本中默认的类加载器有如下几种:

  • 启动类加载器(Bootstrap ClassLoader、C++实现):加载核心类,String类
  • 扩展类加载器(Extension ClassLoader、Java实现):加载扩展类,拓展Java中比较通用的类,只是通用,不是特别重要,最重要的在启动类加载器加载了
  • 应用程序类加载器(Application ClassLoader、Java实现):加载应用classpath中的类,包括我们自己写的类,还有第三方Jar包的类
  • 自定义类加载器(Java实现):需要重写findClass方法。

类加载器的详细信息可以通过Arthas的classloader命令查看

classloader - 查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResource

在这里插入图片描述

  • BootstrapClassLoader是启动类加载器,numberOfInstances是类加载器的数量只有1个,loadedCountTotal是加载器所加载的类的数量为1861个
  • ExtClassLoader是扩展类加载器
  • AppClassLoader是应用程序类加载器
  • DelegatingClassLoader是用来提升反射效率的类加载器
  1. 启动类加载器
  • 启动类加载器(Bootstrap ClassLoader)是由Hotspot虚拟机提供的、使用C++编写的类加载器,Java程序员无法修改或者扩展源代码,所以只关注这个加载器的作用。
  • 作用:默认加载Java安装目录/jre/lib下的类文件,比如rt.jar,tools.jar,resources.jar等,给java程序提供了一个基础的运行环境。

在这里插入图片描述

运行如下代码:

/**
 * 启动程序类加载器案例
 */
public class BootstrapClassLoaderDemo {
    public static void main(String[] args) throws IOException {
        ClassLoader classLoader = String.class.getClassLoader();
        System.out.println(classLoader);

        System.in.read();
    }
}

这段代码通过String类获取到它的类加载器并且打印,本来以为是Bootstrap ClassLoader,结果是null。这是因为启动类加载器在JDK8中是由C++语言来编写的,在Java代码中去获取既不适合也不安全,所以才返回null

在Arthas中可以通过sc -d 类名的方式查看加载这个类的类加载器详细的信息,比如:

在这里插入图片描述

通过上图可以看到,java.lang.String类的类加载器是空的,Hash值也是null。所以只要看到为null,就知道这是启动类加载器

用户扩展基础jar包

如果用户想扩展一些比较基础的jar包,让启动类加载器加载,有两种途径:

  • 打包成jar包,放入jre/lib下进行扩展。不推荐,尽可能不要去更改JDK安装目录中的内容,因为即使放进去由于文件名不匹配的问题也不会正常地被加载(在加载jar包的时候,会对名称进行校验,名称必须符合JVM内部的一些规范)。
  • **使用参数进行扩展。**推荐,使用-Xbootclasspath/a:jar包目录/jar包名进行扩展,参数中的/a代表新增。

【使用参数进行扩展实现流程】

先创建第一个项目,打包成jar包

在这里插入图片描述

再创建第二个项目,在第二个项目的IDEA配置中添加虚拟机参数,就可以加载D:/jvm/jar/classloader-test.jar这个jar包了。

在这里插入图片描述

使用Class.forName获取Jar包的类,可以正常执行初始化,说明自己拓展的Jar包被加载了

在这里插入图片描述

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

继承关系图如下:

在这里插入图片描述

  • ClassLoader类:定义了具体的行为模式,简单来说就是先从本地或者网络获得字节码信息,然后调用虚拟机底层的方法创建方法区和堆上的对象。这样的好处就是让子类只需要去实现如何获取字节码信息这部分代码
  • SecureClassLoader:提供了证书机制,提升了安全性。
  • URLClassLoader:提供了根据URL获取目录下或者指定jar包进行加载,获取字节码的数据的能力。

扩展类加载器和应用程序类加载器继承自URLClassLoader,获得了上述的三种能力。

  1. 扩展类加载器

扩展类加载器(Extension Class Loader)是JDK中提供的、使用Java编写的类加载器。默认加载Java安装目录/jre/lib/ext下的类文件。

在这里插入图片描述

如下代码会打印ScriptEnvironment类的类加载器。ScriptEnvironment是nashorn框架中用来运行javascript语言代码的环境类,他位于nashorn.jar包中被扩展类加载器加载。这些类我们很少用,所以被放到了扩展类加载器中。

/**
 * 扩展类加载器
 */
public class ExtClassLoaderDemo {
    public static void main(String[] args) throws IOException {
        ClassLoader classLoader = ScriptEnvironment.class.getClassLoader();
        System.out.println(classLoader);
    }
}

打印结果如下:

在这里插入图片描述

通过扩展类加载器去加载用户jar包:
  • 放入/jre/lib/ext下进行扩展。不推荐,尽可能不要去更改JDK安装目录中的内容。
  • 使用参数进行扩展使用参数进行扩展。推荐,使用-Djava.ext.dirs=jar包目录进行扩展,这种方式会覆盖掉原始目录,可以追加上原始目录,并使用 ;(windows系统所用符号) :(macos/linux) 进行分隔

如下图中:

在这里插入图片描述

使用引号将整个地址包裹起来,这样路径中即便是有空格也不需要当做特殊字符额外处理。路径中要包含原来ext文件夹,同时在最后加上扩展的路径。

  1. 应用程序加载器

应用程序类加载器会加载classpath下的类文件,默认加载的是项目中的类以及通过maven引入的第三方jar包中的类。

如下案例中,打印出Student(自己写的)和FileUtils(引入的)的类加载器:

/**
 * 应用程序类加载器案例
 */
public class AppClassLoaderDemo {
    public static void main(String[] args) throws IOException, InterruptedException {
        //当前项目中创建的Student类
        Student student = new Student();
        ClassLoader classLoader = Student.class.getClassLoader();
        System.out.println(classLoader);

        //maven依赖中包含的类
        ClassLoader classLoader1 = FileUtils.class.getClassLoader();
        System.out.println(classLoader1);

        Thread.sleep(1000);
        System.in.read();

    }
}

输出结果如下,这两个类均由应用程序类加载器加载。

在这里插入图片描述

Arthas中类加载器相关功能

类加载器的加载路径可以通过classloader –c hash值 查看:

在这里插入图片描述

查看应用程序类加载器所加载的jar包

在这里插入图片描述

文章说明

该文章是本人学习 黑马程序员 的学习笔记,文章中大部分内容来源于 黑马程序员 的视频黑马程序员JVM虚拟机入门到实战全套视频教程,java大厂面试必会的jvm一套搞定(丰富的实战案例及最热面试题),也有部分内容来自于自己的思考,发布文章是想帮助其他学习的人更方便地整理自己的笔记或者直接通过文章学习相关知识,如有侵权请联系删除,最后对 黑马程序员 的优质课程表示感谢。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

车载测试:为什么你投十份简历,只有一两家公司约你?

最根本的原因,就是一方在汲汲渴求,而恰恰另一方呈现出的关键点让其怦然心动。求者心中有所想,而应者恰恰展现了求者所想的那一面。这就是个中奥妙。 程序员在找工作时,在一开始有三件事情会对能否获得面试机会至关重要&#xff1…

C++笔记(STL标准库)

1.STL六大部件 容器 Containers分配器 Allocators:帮容器分配内存算法 Algorithms迭代器 Iterators:算法通过迭代器操作容器里的数据,是一种泛化的指针适配器 Adapters:修改或扩展已有类或函数的接口以满足特定的需求仿函数 Func…

自动秒收录网址导航分类目录模板

自动秒收录网址导航是一个以html5css3进行开发的免费版网址自动收录模板源码。 模板特点:全站响应式H5网站制作技术,一个网站适应不同终端,模板支持网址导航一键采集入库,免规则文章资讯智能批量采集内置伪原创,本地化…

DSA理解理解蓝桥杯例题signature

一、历史 1991年8月,NIST(Nation Institute of Standards and Technology,美国国家标准技术研究所)提出了数字签名算法(DSA)用于他们的数字签名标准(DSS)中。 DSA是算法&#xff0c…

SCI论文发表:寻找论文选题的7种方法 (建议收藏)!

我是娜姐 迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 近期有好几个同学问娜姐关于论文选题的问题:什么样的选题是好的选题-有价值好发表。这篇来分享7种寻找有效选题的方法。 在我们寻找论文选题的过程中,…

Linux配置两个局域网间的网络转发

网络拓扑如上图所示,有192.168.1.0(255.255.255.0),192.168.2.0(255.255.255.0)两个局域网。若要使host1可直接通过ip地址访问host3,则需在host2中配置路由转发。 host2 配置静态路由(系统一般会自动配置) # 添加静…

Electron、QT、WPF三强争霸,该支持谁呢?

Electron、QT、WPF都是跨平台的桌面应用开发框架,都是非常流行的,作为开发者该选用哪个呢?本文从多个角度分析一下。 一、定义 Electron、Qt 和 WPF 都是用于创建桌面应用程序的框架或工具,它们各自有着不同的特点和优势。 Elec…

Windows下安装 Emscripten 详细过程

背景 最近研究AV1编码标准的aom编码器,编译的过程中发现需要依赖EMSDK,看解释EMSDK就是Emscripten 的相应SDK,所以此博客记录下EMSDK的安装过程;因为之前完全没接触过Emscripten 。 Emscripten Emscripten 是一个用于将 C 和 …

论文盲审吐槽多,谁给盲审不负责的老师买单?如何看待浙江大学「一刀切」的研究生学位论文双盲评审制度?

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验,帮助大家尽早适应研究生生活,尽快了解科研的本质。祝一切顺利!—…

Windows11“重置此电脑”后,Edge浏览器在微软应用商店显示“已安装”,但是开始菜单搜索不到的解决办法

Windows11“重置此电脑”后,Edge浏览器在微软应用商店显示“已安装”,但是开始菜单搜索不到的解决办法 为什么重新使用Edge?问题描述不该更新可用更新问过AI(通义千问),并且AI提供方法全都无效。现象 操作步…

<MySQL> 数据库基础

目录 一、数据库概念 (一)什么是数据库 (二)数据库存储介质 (三)常见数据库 二、数据库基本操作 (一)连接数据库 (二)使用数据库 (三&…

免费PDF批量加密工具

最近在找PDF批量加密的软件来着,发现很多都是需要收费的,当然如果平时工作需要用的比较多,支持一下还是ok的,但是多数人还是偶尔用一下所以没有必要买。 工作用的话,一般企业文件、个人隐私资料、重要合同...所有重要文…

测试萌新三天速通python基础(二)列表,字符串,元组,字典,遍历,容器,集合,函数

python基础 字符串下标(索引)切片字符串的替换 replace()字符串拆分 split()字符串的连接 join列表 list列表的增删改查列表的反转 reverse()排序列表嵌套元组 tuple 排序 升序降序交换变量字典 dict查询遍历容器集合函数参数函数的嵌套调⽤函数的返回值模块导⼊的⽅法____name…

YOLOv8独家原创改进: AKConv(可改变核卷积)

1.AKConv原理介绍 地址:2311.11587 (arxiv.org) 摘要:基于卷积运算的神经网络在深度学习领域取得了令人瞩目的成果,但标准卷积运算存在两个固有的缺陷。一方面,卷积运算仅限于局部窗口,无法捕获其他位置的信息, 并且它的采样形状是固定的。 另一方面,卷积核的大小固定为…

中国速度!滑湿人自己的MFC第一课!

前言: 这!是一个!新的专栏! 因为!面向对象的程序设计!已经!学的差不多了! 我谭哥那本大厚书!也快!学完了! 于是!sgq!为…

springboot+layuimini实现树形表格

树形表格实现增删改查 这里写目录标题 效果图前端页面代码前端插件后端代码controllerserviceserviceImpl 实现类Entitymapperxml mybatis代码数据表 效果图 前端页面代码 <!DOCTYPE html> <html lang"en" xmlns:th"http://www.thymeleaf.org"&g…

【机器学习300问】87、学习率这种超参数在优化时选择随机搜索方法,为什么要在对数尺度范围进行随机搜索?

在超参数优化过程中&#xff0c;对数尺度范围进行随机采样对于某些类型的超参数来说是非常有效的&#xff0c;特别是当超参数的有效值跨越几个数量级时。学习率就是这样一种超参数&#xff0c;它可以从非常小&#xff08;例如&#xff09;到相对大的值&#xff08;例如&#xf…

Vscode----远程服务器改名

问题描述 一开始Autodl服务器机子很多,但是我使用vscode的时候他们的名字都一样,导致每次要打开机子是都需要重新输入ssh和密码 解决方法 修改vscode端服务器的名字即可解决 打开远程设置,选择你的ssh配置文件 将Host改为你想要的名字,保存刷新即可 点击访问博客查看更多…

机器学习作业4——朴素贝叶斯分类器

目录 一、理论 一个例子&#xff1a; 二、代码 对于代码的解释&#xff1a; 1.fit函数&#xff1a; 2.predict函数: 三、实验结果 原因分析&#xff1a; 一、理论 朴素贝叶斯分类器基于贝叶斯定理进行分类&#xff0c;通过后验概率来判断将新数据归为哪一类。通过利用贝…

“知识世界”项目的自动化测试

目录 1.项目介绍 1.1 项目功能介绍 2. 项目测试 2.1 需求分析 2.2 测试计划 2.3 设计测试用例 &#xff08;1&#xff09; 设计 登录 的测试用例 &#xff08;2&#xff09;设计 文章列表页 的测试用例 &#xff08;3&#xff09;设计 详情页 的测试用例 &#xff08…