JVM-类加载详解

2023-11-18

一、JVM类加载过程

JVM类加载过程如下图:

JVM类加载过程分为:加载 、链接 、初始化 、使用 、卸载 这五个阶段,其中链接阶段又包括: 验证 、 准备 、 解析 。

  • 加载 :通过类的完全限定名,查找此类的二进制字节码文件,通过该字节码文件创建Class对象。
  • 链接 :包含 验证 、 准备 、 解析 三个阶段:
    • 验证 :确保Class文件复合虚拟机规定的Class文件格式,包含文件格式验证、元数据验证、字节码验证、引用符号验证。
    • 准备 :为类的静态变量分配内存并设置初始化值,注:这里不包含final修饰的静态变量,因为final修饰的静态变量是在编译期分配。
    • 解析 :将常量池的间接引用转换为直接引用,解析包含字段解析、接口解析、方法解析。
  • 初始化 :初始化静态变量和静态块,先初始化父类,再初始化当前类,只有对类主动时才会初始化。
  • 使用 :程序代码执行时使用,new出对象程序中使用。
  • 卸载 :程序代码退出、异常、结束等,执行垃圾回收。

二、类加载时机

  • 创建类的实例,也就是new一个对象。
  • 访问类的静态方法或者静态变量(包含静态变量赋值)。
  • 使用Class.forName()反射类。
  • 子类初始化的时候。
  • JVM启动时标明的启动类。

三、类加载器

类加载器包括启动类加载器、扩展类加载器、系统类加载器、自定义类加载器四种加载器。

  • 启动类加载器(Bootstrap ClassLoader):负责加载Java类的核心类,是用原生代码实现。下面代码可以获得启动类加载器所加载的Java核心类库。

    URL[] urLs = Launcher.getBootstrapClassPath().getURLs();
    for(URL url : urLs){
        System.out.println(url.toExternalForm());
    }
    

    输出如下:

    file:/D:/Develop%20Tools/Java/jdk-8u231/jre/lib/resources.jar
    file:/D:/Develop%20Tools/Java/jdk-8u231/jre/lib/rt.jar
    file:/D:/Develop%20Tools/Java/jdk-8u231/jre/lib/sunrsasign.jar
    file:/D:/Develop%20Tools/Java/jdk-8u231/jre/lib/jsse.jar
    file:/D:/Develop%20Tools/Java/jdk-8u231/jre/lib/jce.jar
    file:/D:/Develop%20Tools/Java/jdk-8u231/jre/lib/charsets.jar
    file:/D:/Develop%20Tools/Java/jdk-8u231/jre/lib/jfr.jar
    file:/D:/Develop%20Tools/Java/jdk-8u231/jre/classes
    
  • 扩展类加载器(Extensions ClassLoader):负责加载JRE的扩展目录lib/ext或者由java.ext.dirs系统属性指定的目录中的JAR包的类。由Java语言实现,父类加载器为Null。

  • 系统类加载器(System Class Loader):负责在JVM启动时加载来自Java命令的-classpath选项、java.class.path系统属性。可以通过ClassLoader.getSystemClassLoader()方法获取当前系统类加载器,一般情况是自定义类加载器的父加载器。由Java语言实现,父类加载器为扩展类加载器。

    System.out.println(ClassLoader.getSystemClassLoader());
    System.out.println(ClassLoader.getSystemClassLoader().getParent());
    

    上面代码输出为:

    sun.misc.Launcher$AppClassLoader@18b4aac2
    sun.misc.Launcher$ExtClassLoader@4eb7f003
    
  • 自定义类加载器(Custom ClassLoader):用户可以通过继承ClassLoader类实现自定义类加载器。由Java语言实现,自定义类加载器的父类是系统类加载器。

四、类加载机制

JVM的类加载机制主要有全盘负责、双亲委派、缓存机制三种加载机制。

  • 全盘负责:当一个类加载器加载某个Class时,该Class所依赖和引用其他Class也会由该类加载器负责加载,除非指定了使用其他类加载器加载。
  • 双亲委派:先让父类加载器加载该Class,只有在父类加载器无法加载该类时才尝试使用自己的类加载器加载。通俗的讲就是在某个特定的类加载器接到加载类请求时,先寄托给父加载器加载,依次递归,如果父加载器可以加载时则成功返回,如果不可以加载就自己去加载。
  • 缓存机制:缓存机制会确保所有加载过的Class都被会缓存,当程序中需要某个Class时,类加载器先从缓存区中搜索该Class,只有缓存区中不存在该Class对象时,系统才会读取该类的二进制数据,并将其转换为Class对象,存入缓存区。这就是为什么我们修改Class文件之后,必须重启JVM才会生效的原因。

其中双亲委派机制优势:

  • 父类加载器成功加载则返回,子类加载器不会再加载,防止了重复加载。
    缓存区。这就是为什么我们修改Class文件之后,必须重启JVM才会生效的原因。

其中双亲委派机制优势:

  • 父类加载器成功加载则返回,子类加载器不会再加载,防止了重复加载。
  • 防止核心API库被随意篡改。比如有一个要加载java.lang.Integer类的请求,通过双亲委派进制加载传递到启动类加载器,在在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载传递的过来的java.lang.Integer,而直接返回已加载过的Integer.class,可以防止核心API被随意篡改。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM-类加载详解 的相关文章

  • Java - 红、绿、蓝获取RGB

    通过致电getRGB int x int y with a BufferedImage对象 得到一个负数 如何将三个不同的值 红色 绿色和蓝色 转换为这个单个负数 使用颜色类 new Color r g b getRGB
  • 最终字段可能尚未/已经初始化[重复]

    这个问题在这里已经有答案了 可能的重复 如何处理抛出检查异常的静态最终字段初始值设定项 https stackoverflow com questions 1866770 how to handle a static final field
  • Java HashMap 嵌套泛型与通配符

    我正在尝试创建包含自定义类的不同子类的哈希集的哈希映射值的哈希映射 如下所示 HashMap
  • Java:无安全管理器:RMI 类加载器已禁用

    您好 我有 RMI 应用程序 现在我尝试从客户端调用服务器上的一些方法 我有以下代码 public static void main final String args try Setting the security manager Sy
  • Java - toString 到 Color

    我一整天都在努力解决这个问题 基本上我做了一个 for 循环 将条目添加到数组列表中 其中一项是 颜色 变量 我已经用过random nextInt为颜色构造函数的红色 绿色和蓝色部分创建新值 我还设置了一个toString方法 这样我就可
  • Java时间转正常格式

    我有 Java 时间1380822000000 我想转换为我可以阅读的内容 import java util Date object Ws1 val a new Date 1380822000000 toString 导致异常 warnin
  • 为本地@ExceptionHandler编写JUnit测试

    我有以下控制器 class Controller ResponseStatus HttpStatus OK RequestMapping value verifyCert method RequestMethod GET public vo
  • 单元测试、集成测试还是设计中的问题?

    我编写了我的第一个单元测试 我认为它过于依赖其他模块 我不确定是否是因为 这是一个复杂的测试 我实际上已经编写了集成测试或 我的设计有问题 我首先要说的是 虽然我有大约 4 年的开发经验 但我从未学过 也没有人教过自动化测试 我刚刚使用 H
  • Java:java.util.Preferences 失败

    我的程序将加密的产品密钥数据保存到计算机上java util Preferences类 系统首选项 而不是用户 问题是 在 Windows 和 Linux 上 尚未在 OSX 上测试过 但可能是相同的 如果我不运行该程序sudo或者具有管理
  • Java 常量枚举[重复]

    这个问题在这里已经有答案了 可能的重复 理解 Java 中的枚举 https stackoverflow com questions 1419835 understanding enums in java 为什么我们应该使用枚举而不是 Ja
  • Java 中通用方法参数的 getClass()

    以下 Java 方法无法编译
  • 用于安装 R 软件包的备用编译器:clang:错误:不支持的选项“-fopenmp”

    我正在尝试在 OS X 10 11 6 上使用 R 版本 3 4 0 安装 rJava 包 install packages rJava type source 我收到以下错误 clang o libjri jnilib Rengine o
  • 从特定 JAR 文件读取资源(文件的重复路径)

    假设您有 jar1 和artifactId 动物园 jar2 和artifactId 动物 两个 jar 都有一个具有相同路径的资源文件 例如 animals animal txt 有什么方法可以从特定的 jar 中读取该文件吗 使用 ge
  • 将 PropertyPlaceholderConfigurer 中的所有属性注入到 bean 中

    我有一个PropertyPlaceholderConfigurer加载多个属性文件 我想通过配置 XML 将合并的属性映射注入到 Spring Bean 中 我可以这样做以及如何做 您只需创建一个属性 bean 并将其用于您的Propert
  • Java给定长度的随机数

    我需要在 Java 中生成一个恰好 6 位数字的随机数 我知道我可以在随机发生器上循环 6 次 但是在标准 Java SE 中还有其他方法可以做到这一点吗 要生成 6 位数字 Use Random http download oracle
  • 线程上下文类加载器和普通类加载器的区别

    线程的上下文类加载器和普通类加载器有什么区别 也就是说 如果Thread currentThread getContextClassLoader and getClass getClassLoader 返回不同的类加载器对象 将使用哪一个
  • 内部类的访问修饰符[重复]

    这个问题在这里已经有答案了 可能的重复 受保护 公共内部类 https stackoverflow com questions 595179 protected public inner classes 我确信这个问题已经被问过 但我找不到
  • 如何在apache POI中读取excel文件的准确单元格内容

    当我读取单元格的内容时 例如如果它是日期格式 它会转换为另一个值 例如 12 31 2099 gt 46052 和 50 00 gt 50 和 50 00 gt 0 5 但我想要的是获取每个单元格的确切字符串值 我的代码是这样的 cell
  • 检查 Java 字符串实例是否可能包含垃圾邮件数据的最简单方法

    我有一个迭代 String 实例的过程 每次迭代对 String 实例执行很少的操作 最后 String 实例被持久化 现在 我想为每次迭代添加一个检查 String 实例是否可能是垃圾邮件的检查 我只需验证 String 实例不是 成人材
  • 如何让JComboBox中的内容居中显示?

    目前我有这个JComboBox 我怎样才能将其中的内容居中 String strs new String 15158133110 15158133124 15158133458 JComboBox com new JComboBox str

随机推荐

  • 如何在csdn免费下载资料?

    1 可以在个人设置里 绑定手机账号奖励整整50分 点下头像一个人中心一账号设置一手机绑定 2 完成任务 任务要在http task csdn net 里才能看到 3 上传有效 有效啊 别上个广告啊 非法啥的 反而还扣了 资源 4 评论资源
  • QT 5.8

    QT与Qt Creator 前者是框架 类似与MFC 而后者是QT的编译器 也可以使用Visual studio编辑 编译需要其他的 Index of new archive qt 5 8 5 8 0
  • MySQL的体系架构

    文章目录 前言 MySQL的Server层 MySQL的存储引擎 1 InnoDB 存储引擎 2 MyISAM 存储引擎 3 Memory 存储引擎 前言 在学习一种事务之前 我们需要先了解事物的基本组成结构 清楚了事物的基本组成结构之后
  • Linux或者ubuntu子系统中OpenMPI的安装

    在Linux中安装MPI Message Passing Interface 需要以下步骤 检查依赖项 首先 确保系统已经安装了必要的编译工具和库文件 运行以下命令更新软件包并安装所需依赖项 sudo apt update sudo apt
  • 【C语言】实现字符串逆序输出(包含空格的字符串)

    1 目的 实现字符串的逆序输出 比如I believe you 变为you believe I的形式 2 基本思路 这里我们先创建一个可以实现逆序打印的函数 将字符串逆序变为 uoy eveileb I 然后再将每个字符串逆序 从而变为yo
  • java 基础重学(一)-面向对象

    一 什么是面向过程 面向过程 是一种以事件为中心的编程思想 编程的时候把解决问题的步骤分析出来 然后用函数把这些步骤实现 在一步一步的具体步骤中再按顺序调用函数 自顶向下 逐步求精 模块化封装函数主张按功能把软件系统逐步细分 对每个涉及到的
  • 华为OD机试真题 Java 实现【整数对最小和】【2022Q4 100分】,附详细解题思路

    一 题目描述 给定两个整数数组array1 array2 数组元素按升序排列 假设从array1 array2中分别取出一个元素可构成一对元素 现在需要取出k对元素 并对取出的所有元素求和 计算和的最小值 注意 两对元素如果对应于array
  • 在win10, win11 家庭版中安装远程桌面服务

    win10 win11 家庭版中提供远程桌面服务 简介 在windows家庭版中 是不提供远程桌面服务的 你没有办法使用远程桌面连接到windows家庭版中 当然 你可用升级windows 版本到专业版 这样就可用享受到windows自带的
  • MySQL从5.6版本到5.7版本的升级过程

    MySQL从5 6版本到5 7版本的升级过程 二进制升级过程 1 介绍 此处因原有的版本就是5 6的 就不再赘述5 6的安装过程了 原有数据库5 6的目录情况 basedir usr local mysql base目录是做的软链 指向my
  • Matplotlib输出中文显示问题

    Matplotlib输出中文显示问题 试过觉得有用的办法 http www 360doc com content 14 0713 12 16740871 394080556 shtml
  • ggplot2读书笔记6:第四章 语法 基础理论

    碎碎念ing 终于结束了 ggplot2 的第一部分 Getting Started 今天开始看第二部分 语法 第四章 Mastering the Grammar 介绍了ggplot2的一些基础语法知识 大概是对前期内容在理论上做一个总结
  • x390拆机 升级内存和硬盘_战66拆机加内存折腾手记

    前言 今年6 18时入HP 战66二代AMD版时就在计划双十一时升级内存到16G 并顺带加个机械硬盘 结果用了4个多月后感觉目前硬盘空间尚无压力 所以只计划加内存 晒单 之前有朋友用过芝奇 说还不错 既有逼格也有保障 没有等到11 11当天
  • openGL增强表面细节----高度贴图

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一 代码 主程序c 效果 前言 现在我们扩展法线贴图的概念 从纹理图像用于扰动法向量到扰乱顶点位置本身 实 际上 以这种方式修改对象的几何体具有一定的优势 例如使表面特征沿
  • 简单的移动阵型补全

    需求 模拟企鹅群以一种三角形的阵型移动 并向目标发动冲击 冲击时候的企鹅不在跟随阵型移动 阵型内的企鹅跟随阵型移动 并且会自动补全阵型 企鹅群体大概是这样的阵型 o o o o o o 可以抽象成一个数组 fromation new int
  • SQL中partition关键字的使用

    最近在写后台语句时候 运用到了partition这样一个关键字 先大致说一下背景 有一种数据表 如下 现在需要取出 每一个人最近的一次打卡时间 思路是 先把数据按照人名分组 然后在每个组里面按照时间排倒叙 最后取出每组的第一条数据即可 pa
  • 【Hadoop学起来】Linux配置$HADOOP_HOME/etc/hadoop/hadoop-env.sh时找不到JAVA_HOME?

    正文之前 今天很气愤 想要学点东西 但是老是被环境所限制 Hadoop这个见鬼的环境 我只是运行单机模式 结果就是都不成功 好不容易磕磕盼盼的终于把啥缺的东西都找出来了结果最后还是失败了 暂时我真的不想去看失败记录 因为快要睡了明天再说吧
  • Premiere Pro 2022有哪些新增功能吸引了你

    Premiere Pro2022正式出现在大家的面前 那么如此大版本的更新 都有哪些变化呢 今天我们就来谈谈pr22版本的变化 安装 Premiere Pro 2022中文 图形和标题 Premiere Pro 中的图形和字幕工作流程具有多
  • 华为星闪联盟:引领无线通信技术创新的先锋

    星闪 NearLink 是由华为倡导并发起的新一代无线短距通信技术 它从零到一全新设计 是为了满足万物互联时代个性化 多样化的极致 创新体验需求而诞生的 这项技术汇聚了中国300多家头部企业和机构的集体智慧 华为更是其中的主要贡献方 在过去
  • 微信小程序scroll-view滚动到指定位置

    自动滚动到指定位置 在小程序开发过程中 为了满足一个特殊的要求 因此需要一个特殊的功能 即在打开小程序数据加载完成的时候 需要页面自动滚动到指定位置 或者页面的底部 在各种度度 狗狗之后 通过各种尝试 算是找到了一个比较完美的方案 微信扫描
  • JVM-类加载详解

    一 JVM类加载过程 JVM类加载过程如下图 JVM类加载过程分为 加载 链接 初始化 使用 卸载 这五个阶段 其中链接阶段又包括 验证 准备 解析 加载 通过类的完全限定名 查找此类的二进制字节码文件 通过该字节码文件创建Class对象