JVM基础(1)——JVM类加载机制

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

一、简介

首先,我们来简单看下Java程序的执行流程:

上图中,典型的Java程序执行流程如下:

  1. 我们在本地编写完Java源程序;
  2. IDE自动帮我们编译成.class文件(也可以手动通过javac命令编译),然后打包成jar包或者war包;
  3. 接着,执行java -jar命令或直接部署到web容器中来运行程序;
  4. 运行时,OS会启动一个JVM进程,JVM会采用 类加载器 将各种.class文件中包含的Java类加载到内存中;
  5. 最后,JVM基于自己的 字节码执行引擎 ,来执行加载到内存中的那些类。

二、类加载机制

Java的类加载机制远没有第一节中描述的那么简单,上述只是让读者了解下整体流程,本节,我们就深入内部,讲解下Java的类加载机制的内部原理。

2.1 完整流程

类从.class二进制数据被加载到 JVM 内存中开始,到卸载出内存为止,它的整个生命周期包括:

加载(Loading)验证(Verification)准备(Preparation)解析(Resolution)初始化(Initialization)使用(Using)卸载(Unloading),共7个阶段。

*加载(Loading)*阶段很简单,当程序执行到需要的类时,JVM就会通过 类加载器 将其加载到内存中。接下来,我们先看下什么是类加载器,然后详细讲解整个类加载流程。

2.2 类加载器

类加载器可以大致划分为以下三类:

Bootstrap ClassLoader

主要负责加载 JDK 安装目录下的核心类库(比如/lib目录下的类),这些核心类库是JVM运行时自身需要用到的。

Bootstrap ClassLoader 采用C++语言实现,也是JVM自身的一部分,开发者不能直接在Java程序中使用。

Extension ClassLoader

主要负责加载 JDK 安装目录下的扩展类库(比如/lib/ext目录下的类),这些扩展类库是JDK按照功能进行模块划分的,一般也是Java程序运行所必需的。

开发者可以在Java程序中直接使用Extension ClassLoader。

Application ClassLoader

负责加载用户类路径(classpath)所指定的类,可以简单的理解成负责加载用户自己开发的Java类。

开发者可以在Java程序中直接使用Extension ClassLoader,这也是默认的类加载器。

除了上述提供到三种类加载器外,开发者也可以自定义类加载器,根据自己的需求去加载类。

2.3 双亲委派机制

JVM的类加载器是有亲子层级结构的,层级结构如下图:

当我们的类加载器需要加载一个类时,首先会委派给自己的父类加载器去加载,最终传到到顶层 的类加载器去加载;如果某个父类加载器发现在 自己负责的范围内 并没有找到这个类,就会下推加载权力给自己的子类加载器。

以上图为例:

  1. 当Application ClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器Extension ClassLoader去完成;
  2. 当Extension ClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给Bootstrap ClassLoader去完成;
  3. 如果Bootstrap ClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用Extension ClassLoader来尝试加载;
  4. Extension ClassLoader也加载失败,则会使用Application ClassLoader来加载,如果Application ClassLoader也加载失败,则会报出ClassNotFoundException异常。

优点

双亲委派机制的优点很明显,可以 避免类的重复加载 ,当父亲已经加载了该类时,子ClassLoader就没有必要再加载一次。

另外,考虑到 安全因素 ,Java核心api中的类不会被随意替换:假设通过网络传递一个名为java.lang.Integer的类,通过双亲委托模式传递到Bootstrap ClassLoader,发现在核心Java API中已经有这个类了,就并不会重新加载网络传递过来的java.lang.Integer,而直接返回已加载过的Integer.class,这样便可以防止核心API库被随意篡改。

2.4 设计类加载器

下面我们通过一个示例,更好地理解下双亲委派机制。Tomcat是常用的web容器,本身是用Java实现的,当我们的程序以war包部署到tomcat后,tomcat启动后的内部JVM需要加载我们程序中的.class文件。那么Tomcat的类加载机制应该如何设计,才能动态加载我们war包中的类到tomcat自身的JVM中去呢?

首先,Tomcat的类加载体系如下图,蓝色部分是Tomcat继承Application ClassLoader实现的自定义类加载器:

Common、Catalina、Shared类加载器用来加载Tomcat自身的一些核心基础类库。同时,Tomcat为每一个部署在其内的web应用都分配了一个对应的WebApp类加载器,就是这个类加载器负责加载我们部署的这个web应用的类,每一个WebApp只负责加载自己对应的那个web应用的class文件,不会传导给上层类加载器去加载。所以, Tomcat的类加载器设计其实是打破了双亲委派机制的 。

至于Jsp类加载器,则是给每一个JSP都准备了一个Jsp类加载器。

三、类加载过程

3.1 验证阶段

根据Java虚拟机规范,需要对加载进来的“.class”文件的内容进行校验,包括验证文件格式、元数据、字节码、符号引用等各种信息,以确认是否符合指定的规范。

验证阶段就是用来做这个事情的,来看下下面的代码:

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

代码示例中,Kafka类用到了ReplicaManager类,所以它们都会在被加载进JVM后进行验证:

3.2 准备阶段

准备阶段,主要是为类及其静态字段分配内存,并将其初始化为默认值。比如,下面的ReplicaManager类:

    public class ReplicaManager {public static int flushInterval;}

当加载阶段、验证阶段都执行完成后,JVM会给类的静态字段分配内存空间,上述代码就是给flushInternal字段赋默认值0,整个过程如下图:

3.3 解析阶段

解析阶段,实际上是把 类的符号引用替换为直接引用 的过程,这一过程底层非常复杂,我们后续章节将进行专门讲解。

3.4 初始化阶段

之前说过,JVM会在准备阶段给类的静态字段分配空间和默认值。而在初始化阶段,就会正式执行类的初始化代码,对类进行初始化操作。什么是初始化代码?我们来看下下面这段代码理解下:

    public class ReplicaManager {public static int flushInterval = Configuration.getInt("replica.flush.interval");public static Map<String,Replica> replicas;static {loadReplicaFromDish():}public static void loadReplicaFromDish(){this.replicas = new HashMap<String,Replica>();}}

对于flushInternal变量,我们通过一个getInt方法从配置中获取值并进行赋值,这个赋值动作在 准备阶段 是不会执行的,而是在 初始化阶段 执行。另外,对于static静态代码块,也是在这个阶段执行的。

在初始化阶段,如果JVM初始化某个类时,发现其父类还没有初始化完成的话,会首先去加载其父类,加载策略就是上一节提到的双亲委派机制。

3.5 使用阶段

没啥好说的,就是在程序中使用类或对象。

3.6 卸载阶段

卸载阶段,就是当对象不再需要使用时,JVM需要进行垃圾回收,这一阶段涉及两个核心过程:存活判定垃圾回收,我们会在后续章节详细讲解。

四、总结

本章,我们介绍了Java的类加载机制及其整个流程,JVM底层的类加载过程的细节非常多,十分复杂,读者如果想要深入,可以参阅The Java Virtual Machine Specification。下一章,我们将看看JVM是如何进行内存区域划分的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024--Django平台开发-Django知识点(五)

day05 django知识点 今日概要&#xff1a; 中间件 【使用】【源码】cookie 【使用】【源码 - Django底层请求本质】session【使用】【源码 - 数据库请求周期中间件】 1.中间件 1.1 使用 编写类&#xff0c;在类型定义&#xff1a;process_request、process_view、process_…

Unity Editor实用功能:Hierarchy面板的对象上绘制按按钮并响应

目录 需求描述上代码打个赏吧 需求描述 现在有这样一个需求&#xff1a; 在Hierarchy面板的对象上绘制按钮点击按钮&#xff0c;弹出菜单再点击菜单项目响应自定义操作在这里的响应主要是复制对象层级路路径 看具体效果请看动图&#xff1a; 注&#xff1a; 核心是对Edito…

控制el-table的列显示隐藏

控制el-table的列显示隐藏&#xff0c;一般的话可以通过循环来实现&#xff0c;但是假如业务及页面比较复杂的话&#xff0c;list数组循环并不好用。 在我们的页面中el-table-column是固定的&#xff0c;因为现在是对现有的进行维护和迭代更新。 对需要控制列显示隐藏的页面进…

【EI会议征稿通知】第三届仿真设计与计算建模国际学术会议(SDCM 2024)

The 3rd International Conference on Simulation Design and Computational Modeling 第三届仿真设计与计算建模国际学术会议&#xff08;SDCM 2024&#xff09; 第三届仿真设计与计算建模国际会议&#xff08;SDCM 2024&#xff09;将于 4 月 26-28 日在中国重庆召开。第二届…

【博士每天一篇文-算法】Graph Structure of Neural Networks

阅读时间&#xff1a;2023-11-12 1 介绍 年份&#xff1a;2020 作者&#xff1a;尤家轩 斯坦福大学 期刊&#xff1a; International Conference on Machine Learning. 引用量&#xff1a;130 论文探讨了神经网络的图结构与其预测性能之间的关系。作者提出了一种新的基于图的…

【leetcode】力扣算法之旋转图像【难度中等】

题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 用例 输入&#xff1a; matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&…

java 体育明星管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web 体育明星管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…

2000-2022各省、地级市风险投资(VC)数据

2000-2022各省、地级市风险投资&#xff08;VC&#xff09;数据 1、时间&#xff1a;2000-2022年 2、范围&#xff1a;350个地级市&#xff0c;34省 3、指标&#xff1a;包含投资机构层面的风险投资原始数据&#xff0c;汇总到省市层面的结果数据&#xff0c;具体指标如下&a…

【Java集合篇】ConcurrentHashMap是如何保证fail- safe的

ConcurrentHashMap是如何保证fail-safe的 ✅典型解析✅拓展知识仓✅分段锁☑️分段锁适用于什么情况&#x1f7e1;分段锁的锁争用情况,是否会带来一定的性能影响✔️分段锁的优缺点&#x1f7e2; 还有哪些其他的线程安全哈希表实现&#x1f7e0;Hashtable和 Collections区别&am…

二叉树及其实现

二叉树 一.树的概念及结构1.1树的概念1.2相关概念 2.二叉树的概念及结构2.1 概念2.2 特殊的二叉树 3.二叉树的遍历3.1 前序、中序以及后序遍历3.2 层序遍历3.3 判断二叉树是否是完全二叉树3.4 二叉树的高度3.5 二叉树的叶子节点个数3.6 二叉树的第k层的节点个数3.7 二叉树销毁3…

Java面向对象综合练习(拼图小游戏),用java图形化界面实现拼图小游戏

1. 设计游戏的目的 锻炼逻辑思维能力利用Java的图形化界面&#xff0c;写一个项目&#xff0c;知道前面学习的知识点在实际开发中的应用场景 2. 游戏的最终效果呈现 Hello&#xff0c;各位同学大家好。今天&#xff0c;我们要写一个非常有意思的小游戏 —《拼图小游戏》 我们…

自行车商城网站网页设计与制作web前端设计html+css+js成品。电脑网站制作代开发。vscodeDrea

【自行车商城网站网页设计与制作web前端设计htmlcssjs成品。电脑网站制作代开发。vscodeDrea】 https://www.bilibili.com/video/BV1wT4y1p7jq/?share_sourcecopy_web&vd_sourced43766e8ddfffd1f1a1165a3e72d7605

您的计算机已被.LIVE勒索病毒感染?恢复您的数据的方法在这里!

引言&#xff1a; 在数字时代&#xff0c;.LIVE勒索病毒如暗夜中的黑暗调&#xff0c;威胁着个人和企业的数字安全。本文将深入介绍.LIVE勒索病毒的特征&#xff0c;提供解密数据的方法&#xff0c;并讨论预防措施&#xff0c;让我们共同筑起数字世界的防护之墙。数据的重要性…

太惨了,又一个程序员被渣的开年大瓜

今天闲暇之余浏览了一下mm&#xff0c;忽然看见一条瓜&#xff1a;某东pdf瓜&#xff0c;一份19页的PDF文件&#xff0c;题为《婚房变赠予&#xff0c;京东渣女出轨连环套设计冤大头程序员》&#xff0c;点进去看了一下&#xff0c;简直炸裂了三观&#xff0c;男同志们一定要保…

什么是预训练Pre-training—— AIGC必备知识点,您get了吗?

Look&#xff01;&#x1f440;我们的大模型商业化落地产品&#x1f4d6;更多AI资讯请&#x1f449;&#x1f3fe;关注Free三天集训营助教在线为您火热答疑&#x1f469;&#x1f3fc;‍&#x1f3eb; 随着人工智能(AI)不断重塑我们的世界&#xff0c;其发展的一个关键方面已经…

数据结构之单调栈、单调队列

今天学习了单调栈还有单调队列的概念和使用&#xff0c;接下来我将对其定义并配合几道习题进行讲解&#xff1a; 首先先来复习一下栈与队列&#xff1a; 然后我们来看一下单调栈的定义&#xff1a; 单调栈中的元素从栈底到栈顶的元素的大小是按照单调递增或者单调递减的关系进…

Javaweb之SpringBootWeb案例的详细解析

SpringBootWeb案例 前面我们已经讲解了Web前端开发的基础知识&#xff0c;也讲解了Web后端开发的基础(HTTP协议、请求响应)&#xff0c;并且也讲解了数据库MySQL&#xff0c;以及通过Mybatis框架如何来完成数据库的基本操作。 那接下来&#xff0c;我们就通过一个案例&#xf…

生信 R语言

11.芯片表达矩阵下游分析 ​rm(list ls())#清除所有变量 options(stringsAsFactors F) #BiocManager::install("CLL") suppressPackageStartupMessages(library(CLL)) data("sCLLex") sCLLex ## ExpressionSet (storageMode: lockedEnvironment) ## as…

centos下系统全局检测工具dstat使用

目录 一&#xff1a;没有需要安装 二&#xff1a;dstat命令参数 三、监测界面各参数含义&#xff08;部分&#xff09; 四、dstat的高级用法 一&#xff1a;没有需要安装 yum install dstat 二&#xff1a;dstat命令参数 有默认选项&#xff0c;执行dstat命令不加任何参数…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷②

2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷2 目录 需要竞赛软件包环境以及备赛资源可私信博主&#xff01;&#xff01;&#xff01; 2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷2 模块一 …