加载过程

  1. Loading

    1. Loading

      1. 双亲委派策略:主要是出于安全考虑

        1. 父加载器不是“类加载器的加载器”,也不是“类加载器的父类加载器”,没有继承关系,父加载器只是子加载器的一个成员变量
      2. LazyLoading

        1. 五种情况
          –new getstatic putstatic invokestatic指令,访问final变量除外
          –java.lang.reflect对类进行反射调用时
          –初始化子类的时候,父类首先初始化
          –虚拟机启动时,被执行的主类必须初始化
          –动态语言支持java.lang.invoke.MethodHandle解析的结果为REF_getstatic
          REF_putstatic REF_invokestatic的方法句柄时,该类必须初始化
      3. ClassLoader的源码

        1. findInCache -> parent.loadClass -> findClass() 说明:现在自己的Cache中查询是否已经加载该类,如果没有加载则在父加载器中查找如在父加载器中找到则返回,否则继续往上一父加载器中查找,指导根加载器如果都没有,则由当前加载器进行加载
      4. 自定义类加载器

        1. extends ClassLoader:继承ClassLoader
        2. overwrite findClass() -> defineClass(byte[] -> Class clazz)
          重写findClass方法
        3. 加密
      5. 混合执行 编译执行 解释执行

        1. 检测热点代码指令:-XX:CompileThreshold = 10000
  2. Linking

    1. Verification:验证文件是否符合JVM规范
    2. Preparation:静态成员变量赋默认值
    3. Resolution:将类、方法、属性等符号引用解析为直接引用,常量池中的各种符号引用解析
      为指针、偏移量等内存地址的直接引用
  3. Initializing

    1. 调用类初始化代码,给静态成员变量赋初始值

类加载器图示
类加载-初始化

  1. Bootstrap:根加载器,加载jdk安装目录lib下rt.jar charset.jar等核心类,由C++实现
  2. Extension:Bootstrap的下一级加载器,主要加载扩展jar包,目录jre/lib/ext/*.jar或由-Djava.ext.dirs指定加载目录
  3. App:加载classpath指定内容,也就是我们自己的编写的代码
  4. Custom ClassLoader:自定义加载器

类加载过程:
类加载-初始化

相关文章: