美文网首页程序员JAVA面试
面试题-001:JVM是如何加载类的?

面试题-001:JVM是如何加载类的?

作者: 有梦想的虫子_2018 | 来源:发表于2020-05-01 18:50 被阅读0次

    JVM如何加载类?

    根据官方文档:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html

    官方文档

    一、类加载步骤

    可以看出类加载到JVM包含三步:类加载(Loading)、链接(Linking)、初始化(Initalizing)


    类加载步骤
    1. 加载(Loading)

      • 找到 Class文件所在的位置
      • Class文件的信息写入JVM方法区(method area)中
        类文件信息包含:类的版本、字段、方法、接口描述等
      • 通过Class文件所生成的对象,放入JVM堆(heap)中
    2. 链接(Linking)

      • 验证(Verification)
        验证Class文件的正确,符合JVM的要求

      • 准备(Preparation)
        为类变量分配内存空间并设置变量类型的默认值。

        public static int a=10;
        

        准备阶段下 a的值为int类型的默认值0。
        注:final 修饰的变量,直接设置为初始化的值。

        public static final int b=10;
        

        准备阶段下 b的值为初始化的值10。

      • 解析(Resolution)
        将常量池中的符号引用转换为直接引用

    3. 初始化(Initialization)
      为链接的准备阶段中的静态变量初始化值,此时a设置初始值10。

    至此,类如何加到JVM中其实已经结束,但是我们能不能发散我们的思维,来达到最大的记忆效果呢?
    比如
    1、类加载时是通过什么机制去加载的?
    2、类加载我们了解到类是放置到了JVM的运行时数据区中,如:方法区、堆。
    那么运行时数据区是怎样划分的呢?
    3、什么情况下JVM不会执行类的初始化流程呢?

    二、类加载机制(双亲委派)

    双亲委派
    • CustomClassLoader,判断是否已经加载,已经加载则返回,没有加载则委托给父类AppClassLoader
    • AppClassLoader,判断是否已经加载,已经加载则返回,没有加载则委托给父类ExtClassLoader
    • ExtClassLoader,判断是否已经加载,已经加载则返回,没有加载则委托给父类BootstrapClassLoader
    • BootstrapClassLoader判断是否已经加载,已经加载则返回,没有加载则查到加载路径下是否有Class文件,有则进行加载,没有则通知ExtClassLoader进行加载
      ……
      如果最后没有找到类,会抛出ClassNotFound异常

    双亲委派机制的核心就是保障类的唯一性和安全性

    三、JVM运行时数据区

    运行时数据区
    运行时数据区中的知识点太多了,如:新生代、老年代、垃圾回收、回收算法……就不在本篇中详解了

    四、什么情况下JVM不会执行类的初始化

    • 子类引用父类的静态字段时,不会触发子类的初始化,只会触发父类的初始化
    • 定义对象数组,不会触发该类的初始化
    • 在使用类名获取Class对象时不会触发类的初始化
    • 在使用Class.forName加载指定的类时,可通过initialize参数设置是否需要对类进行初始化

    面对每一道题目,要学会把自己的思维发散出去。每一篇文章只当自己对知识的总结!

    相关文章

      网友评论

        本文标题:面试题-001:JVM是如何加载类的?

        本文链接:https://www.haomeiwen.com/subject/ozmqghtx.html