JVM第一章类加载机制以及双亲委派模型

JVM类加载机制以及双亲委派模型


一、java代码运行机制

​ 首先对于我们开发者而言,编码文件都是java后缀的编码文件,那这个java后缀文件是怎么运行在我们计算机系统的呢?

​ 通过编译成class文件然后交给jvm执行,如下列流程图:

graph LR
A[java后缀文件: user.java] --打包编译--> B[class后缀文件:user] 
B--->jvm[jvm实例]

subgraph JVM 
	jvm--类加载器-->id3[类加载器]
	id3-->id4[执行代码]
end
二、JVM是如何加载一个类的

一个类的加载一般回经历以下流程

验证
准备
解析
初始化
使用
加载
  • 验证:校验是否符合JVM字节码规范
  • 准备:初始化内存
  • 解析:符号引用替换为直接引用
  • 初始化:执行初始化数据逻辑代码

引入一个案例来解析以上几种状态:

首先JVM什么时候回初始化类呢?那就是代码中使用到这个类的时候。看下面代码:

public class A {
    public static void main(String args[]){
        Replicamanager replicamanager = new Replicamanager(); 
    }
    
    
   public static class Replicamanager{
       
       public static int flushInterval;
       
   } 
}

​ 当jvm进程启动之后 ,先把Class A 加载到内存中去,然后从main方法执行入口,然后代码中明显用到了Replicamanager类,则也会加载Replicamanager类到内存中,则会触发类加载器。从“ReplicaManager.class”字节码文件中加载对应的类到内存里来使用,这样代码才能跑起来。

​ 然后开始验证–准备–解析。

​ 验证A.class 和B.class字节码是否符合规范,在准备A、B class文件,就是初始化A和B的初始引用地址比如B对象的flushInterval默认值等等,之后就是解析:符号引用替换为直接引用

​ 如下图所示:

JVM
使用了B类
类加载
类加载
验证A.class和B.class字节码
初始化A.class和B.class内存
解析
准备
验证
A.class
B.classTB

验证–准备–解析这三个阶段都是准备阶段,这个阶段初始化好了内存空间,也分配了默认值。

初始化(核心)

那么当准备阶段完毕之后就会初始化,接着上面的代码,此时flushInterval默认值也初始化好了就是0,那么初始化阶段,就会这是执行我们初始值代码:

public static class Replicamanager{
       
       public static int flushInterval = 
           Configuration.getInt("replica.flush.interval");
   } 

现在对于flushInterval 准备用Configuration.getInt(“replica.flush.interval”);进行赋值。代码就是在这个时段执行的。

而类初始化还有一个规则:就是如果初始化一个类的时候,发现他的父类还没初始化,那么必须先初始化他的父类

总结一下如下图所示

Jvm
类加载机制
类加载机制
使用了B类
类加载
类加载
A
B
初始化
解析
初始化B.class内存
准备
验证B.class字节码
验证
初始化
解析
初始化A.classs内存
准备
验证A.class字节码
验证
A.class
B.classTB
三、双亲委派机制

(1)启动类加载器 Bootstrap ClassLoader,他主要是负责加载我们在机器上安装的Java目录下的核心类的 相信大家都知道,如果你要在一个机器上运行自己写好的Java系统,无论是windows笔记本,还是linux服务器,是不是都得装一下 JDK? 那么在你的Java安装目录下,就有一个“lib”目录,大家可以自己去找找看,这里就有Java最核心的一些类库,支撑你的Java系统的 运行。 所以一旦你的JVM启动,那么首先就会依托启动类加载器,去加载你的Java安装目录下的“lib”目录中的核心类库。

(2)扩展类加载器 Extension ClassLoader,这个类加载器其实也是类似的,就是你的Java安装目录下,有一个“lib\ext”目录 这里面有一些类,就是需要使用这个类加载器来加载的,支撑你的系统的运行。 那么你的JVM一旦启动,是不是也得从Java安装目录下,加载这个“lib\ext”目录中的类?

(3)应用程序类加载器 Application ClassLoader,这类加载器就负责去加载“ClassPath”环境变量所指定的路径中的类 其实你大致就理解为去加载你写好的Java代码吧,这个类加载器就负责加载你写好的那些类到内存里。

(4)自定义类加载器 除了上面那几种之外,还可以自定义类加载器,去根据你自己的需求加载你的类。

(5)双亲委派机制 JVM的类加载器是有亲子层级结构的,就是说启动类加载器是最上层的,扩展类加载器在第二层,第三层是应用程序类加载器,最后一 层是自定义类加载器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值