zoukankan      html  css  js  c++  java
  • 图解JVM类加载机制和双亲委派模型

    我们都知道以 .java 结尾的 Java 源文件,经过编译之后会变成 .class 结尾的字节码文件。JVM 通过类加载器来加载字节码文件,然后再执行程序。

    类加载机制

    什么时候加载一个类

    那么,什么时候类加载器会加载一个类呢?用到这个类的时候,JVM的类加载器就会加载这个类。用到这两个字说起来很抽象,我用代码和图例来说明。

    有下面这样一段代码,一个类EmergencyPlan,里面有一个main()函数,main()函数做的事情是创建了一个 Account 对象。

    public class EmergencyPlan {
        public static void main(String[] args) {
            Account account = new Account();
        }
    }
    

    我们应该知道运行 JVM 就相当于启动了一个 Java 的进程,它会从程序的主函数,即main()函数开始执行。所以类加载的步骤是这样的:

    加载

    1. 先加载主函数所在的类EmergencyPlan
    2. 由于EmergencyPlan使用了Account,所以继续加载Account

    准备和初始化的区别

    类加载机制总共有这样7个步骤:加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载。接下来先把每个阶段在做什么讲一下,再着重对比一下准备阶段和初始化阶段。

    • 验证阶段:验证字节码文件是否符合JVM的规范。这挺好理解,万一字节码文件被修改过,JVM压根无法执行咋办。所以加载之后先验证一下。
    • 准备阶段:为类分配内存空间,为变量赋初值。
    • 解析阶段:符号引用替换为直接引用。
    • 初始化阶段:执行初始化代码,new对象;执行static代码块;父类没有初始化要先初始化父类。

    用代码和画图来说明一下准备阶段和初始化阶段。

    public class EmergencyPlan {
        public static int id
                = Configuration.getInt("plan_id");
    }
    

    这段代码说的是EmergencyPlan这个类有一个变量id,通过getInt()为其赋值:

    • 准备阶段会为id开辟一个内存空间,但不会执行赋值操作,仅仅是赋予一个初值0。
    • 初始化阶段才会执行getInt()为变量id初始化值。

    类加载的过程就变成了下图所示的样子:

    类加载过程

    类加载器和双亲委派模型

    JVM进行类加载是通过类加载器完成,类加载器是一种亲子层级结构的模型。Java里面的类加载器有这样几种:

    • 启动类加载器。加载 JDK 中 lib 目录中 Java 的核心类库,即$JAVA_HOME/lib目录。
    • 扩展类加载器。加载 lib/ext 目录下的类。
    • 应用程序类加载器。加载我们写的应用程序。
    • 自定义类加载器。根据自己的需求定制类加载器。

    那什么是双亲委派模型呢?类加载器是一种亲自层级结构,就像下图所示:

    双亲委派模型

    比如要加载上面的EmergencyPlan类,应用程序类加载器会先问它的父亲扩展类加载器,你能帮我加载么?扩展类加载器会再问它的父亲启动类加载器,你能帮我加载么?

    显然EmergencyPlan是一个应用程序类。启动类加载器会告诉扩展类加载器,你自己去加载;扩展类加载器就会告诉应该程序类加载器,你自己去加载。最后,应用程序类加载器就自己加载了EmergencyPlan

    流程图总结

    最后来在类加载的流程图上,把双亲委派模型也添加上去。

    流程总结

  • 相关阅读:
    DesignPattern系列__10单例模式
    DesignPattern系列__09设计模式概述
    DesignPattern系列__08UML相关知识
    DesignPattern系列__07合成复用原则
    DesignPattern系列__06迪米特原则
    爬取猫眼电影top100电影
    安卓微信对接H5微信支付出现“商家参数有误,请联系商家解决”的问题处理
    python 通过使用pandas的实现的Excel的批量转换CSV文件的处理
    输入一个字符串,判断字符串中最大对称字串的长度
    面向对象六大设计原则(转载)
  • 原文地址:https://www.cnblogs.com/shuiyj/p/12640400.html
Copyright © 2011-2022 走看看