logo头像
Snippet 博客主题

Java八股文查漏补缺-JVM-2-类加载解析

0 写在前面

  Java八股文查漏补缺系列是针对Java八股复习时,针对在面试时候,问的问题可能比较深入,在JavaGuide网站中的一些八股文可能不够用,根据自己的面试经验进行一些学习补充.

  八股文背不如理解,理解深刻,知道底层原理,才能更加牢固。呜呜!直接上题

本文目标:完善JVM类加载流程!

1. 类生命流程

  1. 加载
  2. 验证
  3. 准备
  4. 解析
  5. 初始化
  6. 使用
  7. 卸载

1 2 3 5按顺序,解析有可能在初始化后面,2 3 4 又称为连接

1.1 加载

干三件事!

  1. 全类名->字节流:通过类的全名获得它的对应的二进制字节流
  2. 字节流->方法区运行的数据结构:字节流所代表的静态存储结构转为方法区中的类的数据结构
  3. 方法区的数据结构->类的class对象:在堆中生成该类的class对象,作为对方法区的数据的访问入口

1.2 连接

验证:保证加载符合当前虚拟机要求

准备:类的静态变量分配内存并且初始化为默认值,而不是程序员所期望的值(初始化才执行)

解析:虚拟机的常量池的符合引用替换为直接引用

1.3 初始化

为类的静态变量赋予正确的初始值

1.4 使用

1.5 卸载

  • 执行了System.exit()方法
  • 正常介数
  • 异常或者错误
  • os错误

2. 类加载器

2.1 结构

image-20240509203211104

这里采用的不是继承,是组合!

分类

  • 从JVM角度:只有启动类加载器(cpp实现)与其他(java实现)
  • 从开发人员角度:
    • 启动类加载器:加载jdk/jre/lib下面,所有以java.*开头的类
    • 扩展加载器:加载jdk/jre/lib/ext下面,所有以javax.*开头的类
    • 应用类加载器:加载用户类路径指定的类

加载机制(双亲委派)

加载类让上级先加载,验证类是否加载自己先验证

好处:

  • 类加载层次清晰
  • 避免类的重复加载
  • 保证安全

双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。

双亲委派机制的打破

重写 loadClass()方法,就可以改变传统双亲委派模型的执行流程。

Tomcat 服务器为了能够优先加载 Web 应用目录下的类,然后再加载其他目录下的类,就自定义了类加载器 WebAppClassLoader 来打破双亲委托机制。这也是 Tomcat 下 Web 应用之间的类实现隔离的具体原理。