JVM类加载机制

article/2025/9/22 4:40:49

文章目录

  • 概述
  • 1. 类加载器
  • 2.类加载过程
  • 3.双亲委派机制
  • 总结

概述

Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能。

虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

什么是类的加载?
类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

类加载器并不需要等到某个类被“首次主动使用”时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误(LinkageError错误)如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。

1. 类加载器

类加载器自顶向下分为:
1.Bootstrap ClassLoader启动类(引导类)加载器: 默认会去加载JAVA_HOME/lib目录下的jar。使用C/C++语言实现的,嵌套在JVM内部。它用来加载Java的核心库(String类……)(JAVA_HOME/jre/lib/rt.jar、resource.jar或sun.boot.class.path路径下的内容),包括加载扩展类加载器和应用程序加载器。没有父加载器。出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类。
2.Extention ClassLoader扩展类加载器: 默认去加载JAVA_HOME/lib/ext目录下的jar。Java语言编写,由sun.misc.LauncherExtClassLoader实现。派生于ClassLoader类。从java.ext.dirs系统属性所指定的目录中加载类库,或从JAVA_HOME/jre/lib/ext子目录(扩展目录)下加载类库。如果用户创建的JAR放在此目录下,也会自动由扩展类加载器加载。
3.Application ClassLoader系统类(应用程序类)加载器: 比如我们的web应用,会加载web程序中ClassPath下的类。java语言编写,由sun.misc.Launcher$AppClassLoader实现。它负责加载环境变量classpath或系统属性 java.class.path指定路径下的类库 对于用户自定义类来说:默认使用系统类加载器进行加载 通过 ClassLoader.getSystemClassLoader() 方法可以获取到该类加载器
4.User ClassLoader用户自定义类加载器: 由用户自己定义
只有被同一个类加载器实例加载并且文件名相同的class文件才被认为是同一个class
在这里插入图片描述
执行java程序时,会启动一个JVM进程,JVM在启动时会做一些初始化操作,比如获取系统参数等等,然后创建一个启动类加载器,用于加载JVM运行时必须的一些类到内存中,同时也会创建其他两个类加载器扩展类加载器和系统类加载器。

2.类加载过程

在这里插入图片描述

首先是加载过程(Loading),它是 Java 将字节码数据从不同的数据源读取到 JVM 中,并映射为 JVM 认可的数据结构(Class 对象),这里的数据源可能是各种各样的形态,比如 jar 文件,class 文件,甚至是网络数据源等;如果输入数据不是 ClassFile 的结构,则会抛出 ClassFormatError。加载阶段是用户参与的阶段,我们可以自定义类加载器,去实现自己的类加载过程。

第二阶段是连接(Linking),这是核心的步骤,简单说是把原始的类定义信息平滑地转入 JVM 运行的过程中。这里可进一步细分成三个步骤:

1,验证(Verification),这是虚拟机安全的重要保障,JVM 需要核验字节信息是符合 Java 虚拟机规范的,否则就被认为是 VerifyError,这样就防止了恶意信息或者不合规信息危害 JVM 的运行,验证阶段有可能触发更多 class 的加载。

2,准备(Pereparation),创建类或者接口中的静态变量,并初始化静态变量的初始值。但这里的“初始化”和下面的显示初始化阶段是有区别的,侧重点在于分配所需要的内存空间,不会去执行更进一步的 JVM 指令。

3,解析(Resolution),在这一步会将常量池中的符号引用(symbolic reference)替换为直接引用。在 Java 虚拟机规范中,详细介绍了类,接口,方法和字段等各方面的解析。

最后是初始化阶段(initialization),这一步真正去执行类初始化的代码逻辑,包括静态字段赋值的动作,以及执行类定义中的静态初始化块内的逻辑,编译器在编译阶段就会把这部分逻辑整理好,父类型的初始化逻辑优先于当前类型的逻辑。再来谈谈双亲委派模型,简单说就是当加载器(Class-Loader)试图加载某个类型的时候,除非父类加载器找不到相应类型,否则尽量将这个任务代理给当前加载器的父加载器去做。使用委派模型的目的是避免重复加载 Java 类型。
所谓类加载过程就是将我们的java原文件通过javac编译之后的产生的字节码文件加载到jvm内存,让jvm去执行字节码指令的过程。

3.双亲委派机制

Java的加载机制是双亲委派机制来加载类,为什么要使用这种方式?这个是为了保证【如果加载的类是一个系统类,那么会优先由Bootstrap ClassLoader 、Extension ClassLoader先去加载,而不是使用我们自定义的ClassLoader去加载,保证系统的安全!】

就是当前类加载器(以系统类加载器为例)在加载一个类时,委托给其双亲(注意这里的双亲指的是类加载器中parent属性指向的类加载器)先进行加载。双亲类加载器在加载时同样委托给自己的双亲,如此反复,直到某个类加载器没有双亲为止(通常情况下指双亲为null,也即为当前的双亲为扩展类加载器,其parent为启动类加载器),然后开始在依次在各自的类路径下寻找、加载class类。

如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行;如果父类加载器还存在器父类加载器,则进一步向上委托,依次递归,最终到达顶层的引导类加载器;如果父类加载器可以完成类加载任务,就成功返回,如果父类无法完成加载,子类加载器才会去加载,这就是双亲委派模式。
优点:
1.可以避免类的重复加载
2.防止核心的API被篡改

总结

jvm中类加载的过程包括:加载,链接(验证,解析,准备),初始化这五个阶段。
1.加载:是类加载的第一个阶段,他要完成三件事:
1通过一个类的全限定名来获取该类的二进制字节流
2.将这个字节流所代表的静态存储结构转化为方法区的运行时结构。
3.内存中生存一个这个类的Class对象,作为方法区这个类的数据访问入口
2.验证:验证时链接的第一个步骤,这个阶段目的是确保Class文件的字节流包含的信息符合java虚拟机规范,保证这些信息不会危害虚拟机自身的安全。其中包括:文件格式检验,元数据检验,字节码检验,符号引用检验。cafe baby魔术
3.准备:该阶段是正式为类中定义的变量(静态变量 被static 修饰的变量)分配内存并设置类变量的初始值。public static int a = 1;那么准备阶段他会把 a赋值为0 而不是1;
4.解析:该阶段时java虚拟机将常量池内的符号引用替换为直接引用的过程。
5.初始化阶段:是类加载过程的最后一个阶段,初始化阶段就是执行类构造器clinit方法的过程比如说刚才的 a这个类变量就会复制为1。


http://chatgpt.dhexx.cn/article/IHyipRll.shtml

相关文章

JVM:类加载机制

类加载器 什么是类加载器 ​ 类加载器的作用负责从磁盘中或者网络中加载class文件,classloader只负责加载class文件,类加载器通过一个类的全限定名来获取描述此类的二进制字节流。类加载器虽然用于实现加载动作,但它在Java程序中起到的作用…

JVM类的加载机制

1 类的加载机制 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象&#xf…

jvm之java类加载机制和类加载器(ClassLoader)的详解

手把手写代码:三小时急速入门springboot—企业级微博项目实战--->csdn学院 当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成3个步…

二叉树的遍历

遍历一棵二叉树有很多种方法。假如用D、L、R分别代表二叉树的根结点、左子树、右子树,那么要遍历这棵二叉树,方法就有6种:DLR、DRL、LDR、LRD、RDL、RLD。一般在遍历时遵循先左后右的原则,因此常用的遍历方法有三种:DL…

二叉树的遍历详解

概述 二叉树的遍历是一个很常见的问题。二叉树的遍历方式主要有:先序遍历、中序遍历、后序遍历、层次遍历。先序、中序、后序其实指的是访问父节点的次序。在遍历过程中,若访问顺序是父节点-左孩子节点-右孩子节点,就是先序遍历,…

“二叉树遍历“详解 以及 二叉树的实现

目录 一.二叉树的遍历 1.二叉树的遍历的解释: 2.二叉树的遍历有三种递归结构 (1) 实现先序遍历: (2) 实现中序遍历: (3) 实现后序遍历: (4) 二叉树的层序遍历 层序遍历代码: 二.二叉树的递归实现相关函数讲解…

二叉树遍历详解

二叉树的遍历方式是最基本,也是最重要的一类题目,我们将从「前序」、「中序」、「后序」、「层序」四种遍历方式出发,总结他们的递归和迭代解法。 一、二叉树定义 二叉树(Binary tree)是树形结构的一个重要类型…

讲透学烂二叉树(三):二叉树的遍历图解算法步骤及JS代码

二叉树的遍历是指不重复地访问二叉树中所有结点,主要指非空二叉树,对于空二叉树则结束返回。 二叉树的遍历分为 深度优先遍历 先序遍历:根节点->左子树->右子树(根左右),有的叫:前序遍历…

二叉树的中序遍历算法(Java三种实现方法)

文章目录 题目一、二叉树的节点定义二、三种遍历方法1.递归算法思想 2.迭代算法思想 3.Morris 中序遍历算法思想 总结 题目 给定一个二叉树的根节点 root ,返回它的 中序 遍历 一、二叉树的节点定义 public class TreeNode {int val;TreeNode left;TreeNode righ…

二叉树遍历的几种常见方法

二叉树的遍历方法 一.二叉树分类: 完全二叉树满二叉树扩充二叉树平衡二叉树 二.二叉树的四种遍历方式: 前序遍历(先根,再左,最后右)中序遍历(先左,再根,最后右&#…

二叉树的三种遍历方式

目录 1.二叉树的结构: 2.二叉树的前序遍历: 3.二叉树的中序遍历: 4.二叉树的后序遍历: 5.二叉树前、中、后序的代码实现: 前序遍历函数: 中序遍历函数: 后序遍历: 完整代码&am…

图解二叉树的三种遍历

1、二叉树的遍历 前序遍历:根结点 —> 左子树 —> 右子树 中序遍历:左子树—> 根结点 —> 右子树 后序遍历:左子树 —> 右子树 —> 根结点 层次遍历:仅仅需按层次遍历就可以 前序遍历:1 2 4 5 7…

二叉树的遍历【 详细讲解 】

二叉树的遍历 一共有4种遍历 先看图,对于这个图进行4种遍历的讲解 1、 先序遍历 定义:若二叉树为空,则空操作;否则 (1)访问根节点(2)先序遍历左子树(3&#…

二叉树的创建及遍历方法

目录 1、二叉树的定义及特点 2、满二叉树和完全二叉树的概念 3、二叉树的存储结构 4、创建二叉树 5、树的四种遍历方法 6、结果及其分析 1、二叉树的定义及特点 二叉树是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为&#…

二叉树遍历(图解)

二叉树的顺序存储结构就是用一维数组存储二叉树中的节点,并且节点的存储位置,也就是数组的下标要能体现节点之间的逻辑关系。—–>一般只用于完全二叉树 链式存储—–>二叉链表 定义: lchild | data | rchild(两个指针域&…

图解二叉树及二叉树遍历

二叉树及二叉树遍历 完全二叉树二叉树的遍历遍历的性质 1、完全二叉树 对于一棵具有n个节点的二叉树(按层序编号),如果编号为i的节点与同样深度的满二叉树中编号为i的节点在二叉树的位置完全相同,则为完全二叉树。 换句话来说&a…

数据结构--二叉树遍历(详细过程)

目录 一、什么是二叉树? 二、二叉树的遍历 1. 先序遍历 2. 中序遍历 3.后序遍历 4. 遍历的推导 三、重要的事情 一、什么是二叉树? 1. 二叉树:一种树形结构,特点是每个结点至多只有两颗子树,并且子树有左右之分…

图解法:三分钟掌握二叉树的三种遍历

二叉树作为树中的一种特殊存在机制,人们对于它的排序总结出来了三种方式,让我们一起探寻它的魅力吧! 测试对象 1.先序遍历 首先看一下排序规则 先访问根节点 再先序访问左子树 再先序访问右子树 看上面的素材,得知根节点为…

二叉树的各种遍历算法以及实例

一、二叉树 在计算机科学中,树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构。二叉树是每个节点最多有两个子树的有序树。通常子树被称作“左子树”(left s…

二叉树的四种遍历方法(前序遍历、中序遍历、后序遍历、层序遍历)有图有真相!!!

文章目录 二叉树的四种遍历方式前序遍历(Preorder Traversal)中序遍历(Inorder Traversal)后序遍历(Postorder Traversal)层序遍历(Level Order Traversal) 二叉树的四种遍历方式 相…