JVM的类加载过程详细说明

 更新时间:2021年06月01日 17:01:26   作者:god-jiang  
近来读了《深入理解JVM虚拟机》的部分内容,对JVM也慢慢有个整体的认识,今天就来分享一下我对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类加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决java压缩图片透明背景变黑色的问题

    解决java压缩图片透明背景变黑色的问题

    这篇文章主要介绍了解决java压缩图片透明背景变黑色的问题,需要的朋友可以参考下
    2014-04-04
  • 解析Java的Hibernate框架中的持久化类和映射文件

    解析Java的Hibernate框架中的持久化类和映射文件

    这篇文章主要介绍了Java的Hibernate框架中的持久化类和映射文件,Hibernate是Java的SSH三大web开发框架之一,需要的朋友可以参考下
    2015-12-12
  • springBoot整合rabbitmq测试常用模型小结

    springBoot整合rabbitmq测试常用模型小结

    这篇文章主要介绍了springBoot整合rabbitmq并测试五种常用模型,本文主要针对前五种常用模型,在spirngboot框架的基础上整合rabbitmq并进行测试使用,需要的朋友可以参考下
    2022-01-01
  • 在SpringBoot环境中使用Mockito进行单元测试的示例详解

    在SpringBoot环境中使用Mockito进行单元测试的示例详解

    Mockito特别适用于在Spring Boot环境中进行单元测试,因为它能够轻松模拟Spring应用中的服务、存储库、客户端和其他组件,通过使用Mockito,开发者可以模拟外部依赖,从而使单元测试更加独立和可靠,本文给大家介绍了在Spring Boot环境中使用Mockito进行单元测试
    2024-01-01
  • MyBatis框架实现一个简单的数据查询操作

    MyBatis框架实现一个简单的数据查询操作

    本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的可以了解一下
    2024-12-12
  • idea的使用之关于tomcat热部署的教程

    idea的使用之关于tomcat热部署的教程

    这篇文章主要介绍了idea的使用之关于tomcat热部署的教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Java Web监听器如何实现定时发送邮件

    Java Web监听器如何实现定时发送邮件

    这篇文章主要介绍了Java Web监听器如何实现定时发送邮件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • 从SpringBoot打war包并配置外部Tomcat运行的全流程

    从SpringBoot打war包并配置外部Tomcat运行的全流程

    由于其他原因,我们需要使用SpringBoot打成war包放在外部的Tomcat中运行,本文就以一个案例来说明从SpringBoot打war包到Tomcat配置并运行的全流程经过,需要的朋友可以参考下
    2024-06-06
  • 如何用Java实现排列组合算法

    如何用Java实现排列组合算法

    本文主要介绍了如何用Java实现排列组合算法,对算法感兴趣的同学,可以参考一下,理解其原理,并且试验一下。
    2021-05-05
  • SpringBoot MongoDB详细使用教程

    SpringBoot MongoDB详细使用教程

    这篇文章主要介绍了SpringBoot整合Mongodb实现简单的增删查改,MongoDB是一个以分布式数据库为核心的数据库,因此高可用性、横向扩展和地理分布是内置的,并且易于使用。况且,MongoDB是免费的,开源的,感兴趣的朋友跟随小编一起看看吧
    2022-10-10

最新评论