首页 > 技术文章 > Class load 机制

kakacbing 2018-05-17 22:19 原文

学习 Java SPI 机制时,回顾下 class 的加载机制!

问题:

  • 什么是类的装载?
  • 类的装载条件?
  • 类装载过程?
  • 类卸载条件?

延伸:

  • classpath 是什么?在 JVM 中有什么作用?
  • SPI 机制是什么?怎么使用?
  • 查看 JVM 装载类的方法

一、什么是类的装载

Class 是 JVM 的入口,即 JVM 执行的正是 Class 字节码指令。那么理所当然的 JVM 是需要将要使用的类装载到内存中的。

二、类的加载条件

类只有被使用的时候才会装载,虚拟机是不会无条件的装装 Class 类型的。主要分为下面6种情况,类会主动被虚拟机装载。

  • 创建一个类的实例时。使用 new 、克隆、反序列化等;
  • 调用类的静态方法。对应的字节码指令是 invokestatic ;
  • 使用类的 static 静态字段时(除 final 常量);
  • 使用反射类的方法时;
  • 初始化子类时,虚拟机会先初始化父类。所以 Java 第一个加载的类是 java.lang.Object ;
  • 启动虚拟机的类的 main 方法。

三、类的装载流程

加载,连接,初始化

四、classpath 的作用

查看 Java 文档,可以得出 classpath 从字面意思就是指 class 所在路径,这个路径可以是目录,jar ,zip 。那就说白了 这个路径就是虚拟机查找类的地址。

五、Java SPI 机制

SPI 是 Servie Provider Interface 的缩写,意思就是服务扩展接口 。主要是被框架的开发人员使用。

当服务的提供者提供了一种接口的实现之后,需要在 classpath 下的 META-INF/services/ 目录里创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类。当其他的程序需要这个服务的时候,就可以通过查找这个jar包(一般都是以 jar 包做依赖)的 META-INF/services/ 中的配置文件,配置文件中有接口的具体实现类名,可以根据这个类名进行加载实例化,就可以使用该服务了。JDK中查找服务的实现的工具类是:java.util.ServiceLoader。

可参考此篇博文 Java中SPI机制深入及源码解析 。

六、查看 JVM 装载类的方法

那么如何查看类的装载,或者说哪些类会被装载呢?

程序启动时:

## 运行时加 启动参数
-verbose:class
-XX:+TraceClassPaths

程序启动后:

## 使用 jinfo [pid]
jinfo [pid]
## 观察 java.class.path

推荐阅读