JVM中Class的加载过程

Class加载过程

一、Loading

  • 加载是指通过动态计算来查找具有特定名称的类或接口类型的二进制形式的过程

  • LazyLoading五种情况

    1. new、get-static、put-static、invoke-static指令,访问final变量除外

    2. java.lang.reflect对类进行反射时调用

    3. 初始化子类的时候,父类首先初始化

    4. 虚拟机启动时。被执行的主类必须初始化

    5. 动态语言支持java.lang.invoke.MethodHandle解析的结果为REF>get-static、REF>put-static、REF>invoke-static的方法句柄时,该类必须初始化

  • CLassLoader源码解析

在这里插入图片描述

  • JIT编译器的工作模式

    • 混合执行: 通过“-Xmixed”参数设定
    • 编译执行: 通过“-Xint”参数设定
    • 解释执行: 通过“-Xcomp”参数设定
    • 检测热点代码:-XX:CompileThreshold=10000
  • 自定义加载器

    1. 继承 ClassLoader

    2. 重写 findClass

      1. 通过ByteArrayOutputStream将本地的java文件转化为字节码文件
        1. 这一步可以进行字节码文件的加密操作
      2. 通过defineClass来调用本地方法将字节码文件转化为CLass
      import java.io.ByteArrayOutputStream;
      import java.io.File;
      import java.io.FileInputStream;
      
      public class ClassLoadCustom extends ClassLoader{
          public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
              ClassLoader classLoader = new ClassLoadCustom();
              Class<?> clazz = classLoader.loadClass("cn.Custom");
              Custom o = (Custom) clazz.newInstance();
              System.out.println(o.test());
      
          }
          @Override
          protected Class<?> findClass(String name) throws ClassNotFoundException {
              File file =new File("E:/source-analysis/Java/JVM",name.replaceAll(".","/").concat(".class"));
              try {
                  FileInputStream fis = new FileInputStream(file);
                  ByteArrayOutputStream baos = new ByteArrayOutputStream();
                  int len = 0;
                  while ((len = fis.read()) !=0){
                      baos.write(len);
                  }
                  byte[] bytes = baos.toByteArray();
                  baos.close();
                  fis.close();
                  return defineClass(name,bytes,0,bytes.length);
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return super.findClass(name);
          }
      }
      
      public class Custom {
          public String test(){
              return "classloader -> custom";
          }
      }
      

二、Linking

  • verification(验证)
    • 验证可确保类或接口的二进制表示在结构上正确
  • preparation(准备)
    • 准备工作包括static为类或接口创建字段(类变量和常量)
  • resolution of symbolic references (解析符号引用)
  • 将类、方法、属性等符号引用解析为直接引用
    • 常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用

三、Initialzing

  1. 类或接口类型T将在以下任何一种首次出现之前立即初始化:
    1. T is a class and an instance of T is created
    2. A static method declared by T is invoked
    3. A static field declared by T is assigned
    4. A static field declared by T is used and the field is not a constant variable
  2. 该过程假定该Class对象已经过验证和准备,并且该Class对象包含指示四种情况之一的状态:
    1. Class对象已经过验证和准备,但尚未初始化。
    2. Class对象正在由某些特定的线程初始化T
    3. Class对象已完全初始化并可以使用。
    4. Class对象处于错误状态,可能是因为尝试了初始化而失败了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值