JVM的类加载过程详细说明

一、基础知识

我们平时写的Java写代码一般都是.java文件,编译成为.class字节码文件,然后类加载器把.class文件加载到JVM内存中,接下来JVM就执行我们的字节码文件,整个过程就是这样。

画个图方便大家好理解:

类加载过程其实非常琐碎且复杂,但是我们只要把握其中的核心工作原理即可

一个类从加载到使用会经历以下步骤:

加载-〉验证-〉准备-〉解析-〉初始化-〉使用-〉卸载

以以下ClassLoadDemo类代码举例:

/**
 * @author god-jiang
 * @date 2021/5/29
 */
public class ClassLoadDemo {

    private static int count = 666;

    public static void main(String[] args) {
        ReplicaManager replicaManager = new ReplicaManager();
    }
}

二、加载

那么什么时候会加载一个类呢?答案很简单,当你使用到这个类的时候JVM就会去加载。示例代码main函数是入口,会加载ClassLoadDemo.class字节码,又因为main函数使用了ReplicaManager.class,所以继续加载。

三、验证

验证这一步,是根据JVM规范,来校验你加载进来的.class文件的内容是否符合规范。当你的.class文件被人恶意修改了,字节码不符合JVM规范,那么JVM是没法执行这个字节码的。所以.class被加载到内存中需要验证,通过了之后才能交给JVM来运行

四、准备

准备这一步,就是给你的class中的类分配一定的内存空间,比如ClassLoadDemo类,就会给它分配内存空间,然后给它里面的static变量分配内存空间,给一个默认的初始值。

PS:int的默认值为0,boolean的默认值是false,引用类型的默认值为null,以此类推。

五、解析

解析这一步,实际上就是把符号引用替换为直接引用的过程。这一部分涉及JVM底层,有点复杂,所以不再深究。

以上三步,就核心就是“准备阶段”。因为这个阶段是给加载进来的类分配好了内存空间,类变量也分配了内存空间,并且给了默认的初始值,这个概念,大家心里一定要有。

六、核心阶段:初始化

上面讲过准备阶段会给类变量分配一个内存空间,然后给初始值。但是赋值这一段逻辑在哪里执行呢?答案就是在初始化阶段。

以上的示例代码ClassLoadDemo.class的count变量在准备阶段就是给一个默认值0,但是到了初始化就会赋值为666。

知道了类的加载过程,那么什么时候初始化一个类呢?这里有一个非常重要的规则,就是如果初始化一个类,发现他的父类还没初始化,那么必须先初始化他的父类。

到这里大家应该对类加载的整个过程都有一定的了解,我再根据以上内容画一个张图方便理解。

现在相信大家已经搞明白了整个类加载从触发时机到初始化的过程了,那么还有一个重要的知识点是类加载器,接着分享。

类加载器

JVM的类加载器主要有四种,Bootstrap ClassLoader、Extension ClassLoader、Application ClassLoader,还有一个是自定义类加载器。接下来我来介绍一下他们。

启动类加载器

Bootstrap ClassLoader主要负责加载我们在电脑上安装的Java目录下的核心类。比如我们安装的JDK下就有一个lib目录,里面放着Java最核心的类,支持着Java系统的运行。

扩展类加载器

Extension ClassLoader也是类似的,在我们安装的JDK中有一个lib/ext目录,这里面有一些类就是需要使用这个类加载器加载,支持你的Java系统运行。

应用程序类加载器

Application ClassLoader负责去加载ClassPath环境变量所指定的类,其实可以大概理解为加载你写好的Java代码,然后这个类加载器帮我们把写好的代码加载到内存中运行。

自定义类加载器

除了以上的三种类加载器,我们还可以自定义类加载器,根据自己的需求加载类。

七、双亲委派机制

JVM的类加载器是有亲子层级结构,启动类加载器是处于最上层的,扩展类加载器在第二层,第三层是应用程序类加载器,最后一层是自定义加载器。

双亲委派机制说的是,假设你的应用程序需要加载一个类,它会首先委派给自己的父类加载器去加载,最后到Bootstrap ClassLoader加载器。

如果最上层的类加载器加载不了,他就会下推权利给下面的类加载去加载,一层层下来。

八、总结

今天分享了类加载过程还有类加载器的相关知识,主要以我的学习理解还有图来更加直观的理解这个知识点。

希望以上的内容对你们有所帮助。

到此这篇关于JVM的类加载过程详细说明的文章就介绍到这了,更多相关JVM类加载内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • jvm运行原理以及类加载器实例详解

    JVM运行原理 首先从".java"代码文件,编译成".class"字节码文件,然后类加载器将".class"字节码文件中的类给加载带JVM中,最后就是JVM执行写好的代码.执行过程如下图 类加载器 类加载过程 加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载 加载 一旦JVM进程启动之后,一定会先把类加载到内存中,然后从main()方法的入口代码开始执行 public class

  • 详解JVM类加载机制及类缓存问题的处理方法

    前言 大家应该都知道,当一个Java项目启动的时候,JVM会找到main方法,根据对象之间的调用来对class文件和所引用的jar包中的class文件进行加载(其步骤分为加载.验证.准备.解析.初始化.使用和卸载),方法区中开辟内存来存储类的运行时数据结构(包括静态变量.静态方法.常量池.类结构等),同时在堆中生成相应的Class对象指向方法区中对应的类运行时数据结构. 用最简单的一句话来概括,类加载的过程就是JVM根据所需的class文件的路径,通过IO流的方式来读取class字节码文件,并通

  • 一文读懂Jvm类加载机制

    前言 一个月没更新了,这个月发生了太多的事情,导致更新的频率大大降低,不管怎样收拾心情,技术的研究不能落下! jvm作为每个java程序猿必须了解的知识,博主推荐一本书<深入理解Java虚拟机>,以前博主在学校的时候看过几遍,每一次看都有新的理解.加上工作了也有一年多的时间了,有必要好好总结一番~ 什么是jvm 平常我们编写代码都是编写的.java文件,怎么部署到机器上运行呢?通过打jar包或者war包,然后部署运行. 如果看过jar包的内容那么就能知道,我们写的.java文件全部被编译成了.

  • JVM中ClassLoader类加载器的深入理解

    JVM的体系结构图 先来看一下JVM的体系结构,如下图: JVM的位置 JVM的位置,如下图: JVM是运行在操作系统之上的,与硬件没有直接的交互,但是可以调用底层的硬件,用JIN(Java本地接口调用底层硬件) JVM结构图中的class files文件 class files文件,是保存在我们电脑本地的字节码文件,.java文件经过编译之后,就会生成一个.class文件,这个文件就是class files所对应的字节码文件,如下图: JVM结构图中的类加载器ClassLoader的解释 类加

  • 通俗讲解JVM的类加载机制

    前言 我们很多小伙伴平时都是做JAVA开发的,那么作为一名合格的工程师,你是否有仔细的思考过JVM的运行原理呢. 如果懂得了JVM的运行原理和内存模型,像是一些JVM调优.垃圾回收机制等等的问题我们才能有一个更清晰的概念. 为了走进JVM,深入了解底层,王子打算写一个JVM的专题,留下自己对JVM探索的足迹,同时也希望能帮到小伙伴们更好的理解JVM. 那我们开始吧. JAVA代码的运行流程 首先我们就来聊一聊JAVA代码是怎么运行起来的,这部分比较基础相信大家都知道,就当成是个复习吧. 我们编写

  • JVM类加载机制原理及用法解析

    一.JVM 类加载机制 JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 1. 加载: 加载是类加载过程中的第一个阶段,这个阶段会在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的入口.注意这里不一定非得要从一个 Class 文件获取,这里既 可以从 ZIP 包中读取(比如从 jar 包和 war 包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将 JSP 文件转换成对应的

  • 浅谈JVM核心之JVM运行和类加载

    前言 本篇博客将写一点关于JVM的东西,涉及JVM运行时数据区.类加载的过程.类加载器.ClassLoader.双亲委派机制.自定义类加载器等,这些都是博主自己的一点理解,如果有误,欢迎大家评论拍砖~ 关于JVM运行时数据区 JVM运行时数据区 关于类加载 class文件加载至内存,链接(校验.解析),初始化:最终形成JVM可以直接使用的JAVA类型的过程. 加载:在方法区形成类的运行时数据结构:在堆里面形成该类的Class对象,作为访问方法区的入口. 加载 链接:class文件是否存在问题:一

  • jvm类加载器基础解析

    [类加载器简介] 类加载器(classloader)用于将类的class文件加载到JVM虚拟机.JVM有三种加载器,引导类加载器器(bootstrapclassloader).扩展类加载器(extensionsclassloader)和应用类加载器(applicationclassloader),另外还可以继承java.lang.ClassLoader类创建自定义加载器. [类加载器种类] 1.引导类加载器(BootStrap):并不是一个Java类,采用C++语言编写.内嵌在JVM内核里面,使

  • JVM类加载机制详解

    一.先看看编写出的代码的执行过程: 二.研究类加载机制的意义 从上图可以看出,类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行. 研究类加载机制的第二个目的是让程序能动态的控制类加载,比如热部署等,提高程序的灵活性和适应性. 三.类加载的一般过程 原理:双亲委托模式 1.寻找jre目录,寻找jvm.dll,并初始化JVM: 2.产生一个Bootstrap Loader(启动类加载器): 3.Bootstrap Loader自动加载E

  • JVM的类加载过程以及双亲委派模型详解

    jvm 的主要组成部分 类加载器(ClassLoader) 运行时数据区(Runtime Data Area) 执行引擎(Execution Engine) 本地库接口(Native Interface) jvm 运行时数据区的组成 方法区: ①方法区主要用来存储已被虚拟机加载的类信息(构造器,接口定义).常量.静态变量和运行时常量池等数据. ②该区域是被线程共享的. ③方法区里有一个运行时常量池,用于存放静态编译产生的字面量和符号引用.该常量池具有动态性,也就是说常量并不一定是编译时确定,运行

随机推荐