JAVA面试——类加载机制

  • 生命周期包括:加载、连接(验证、准备、解析)、初始化、使用、卸载
  • 类初始化:
    • 遇到new、getstatic、putstatic、invokestatic四条字节码指令时;常见场景:使用new实例化对象,读取或设置一个类的静态字段、调用一个类的静态方法
    • 使用java.lang.reflect包的方法对类进行反射调用
    • 初始化类时,父类没有初始化
    • 虚拟机启动,用户指定一个要执行的主类,主类没有初始化
    • java.lang.invoke.MethodHandle实例解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,句柄对应的类没有初始化
  • 加载阶段需要完成3件事:
    • 通过一个类的全限定名来获取定义此类的二进制字节流
    • 将这个字节流所表示的静态存储结构转化为方法区的运行时数据结构
    • 在内存中生成一个代表此类的java.lang.Class对象,作为方法区这个类的各种数据访问入口
  • 验证:
    • 确保Class文件的字节流包含的信息符合虚拟机要求
    • 文件格式验证:保证输入字节流可以正确解析并存储于方法区内
    • 元数据验证:对元数据信息进行语义校验,保证不存在不符合JAVA语言规范的元数据信息
    • 字节码验证:对方法体进行校验分析
    • 符号引用验证:符号引用转化为直接引用
  • 准备
    • 为类变量分配内存(方法区)并设置变量初始值
  • 解析
    • 将常量池中的符号引用替换为直接引用
  • 初始化
    • 执行类构造器<clinit>()方法的过程
    • <clinit>()方法是由编译器自动收集类中的所有变量的赋值动作和静态语句块中的语句合并产生的
  • 类加载器:
    • 通过一个类的全限定名来获取描述此类的二进制字节流(JAVA虚拟机外)
    • 加载器分类:
      • 启动类加载器
        • C++实现,是虚拟机自身一部分
      • 所有其他的类加载器
        • Java语言实现,独立于虚拟机外部,继承自抽象类java.lang.ClassLoader
    • 按照层次划分:
      • 启动类加载器
      • 扩展类加载器
      • 应用程序类加载器
    • 类加载的双亲委派模型
      • 工作流程
posted @ 2019-02-25 21:18  李怕怕  阅读(758)  评论(0编辑  收藏  举报