类卸载指的是在JVM中清除无用类的一种机制。当一个类被加载进JVM后,它会一直留在内存中,直到其不再被引用或者程序结束。类卸载是JVM在运行时,对内存空间的优化机制之一。那么什么情况下会触发类卸载机制呢?
触发条件
在Java虚拟机规范中,明确了以下两种情况下会触发类卸载机制:
- 当类的所有实例都被GC标记为可回收状态时,该类才会被卸载。
- 当类加载器被GC回收时,与该类加载器所加载的所有类都会被卸载。
示例说明
接下来我们通过两个具体的示例来进一步了解类卸载的触发条件。
示例1
代码:
public class Test1{
public static void main(String[] args) {
Test1 test1 = new Test1();
test1 = null;
System.gc(); // 手动触发垃圾回收器
System.out.println("gc is done");
}
}
该示例中我们定义了一个Test1的类,然后在main方法中,创建一个Test1对象,并将其赋值为null。接着,手动触发垃圾回收器,并输出一个字符串。该示例中,由于Test1对象没有被引用,当垃圾回收器执行时,该对象会被标记为可回收状态。当所有实例都被标记为可回收状态后,该类就可以被卸载了。
示例2
代码:
public class Test2 {
public static void main(String[] args) throws Exception {
URL url = new URL("file:/Users/user/Desktop/");
URLClassLoader loader = new URLClassLoader(new URL[]{url});
Class clazz = loader.loadClass("Test");
Object object = clazz.newInstance();
object = null;
loader = null;
clazz = null;
System.gc(); // 手动触发垃圾回收器
System.out.println("gc is done");
}
}
在该示例中,我们首先创建一个URLClassLoader,用于加载文件路径为”/Users/user/Desktop/”下的所有类。接着,我们通过loadClass方法加载名为”Test”的类,并创建该类的一个实例。然后,我们将其赋值为null,并将URLClassLoader、Class实例同样赋值为null。执行完这些操作后,我们手动触发垃圾回收器,并输出一个字符串。在该示例中,由于URLClassLoader实例被赋值为null,与其所加载的所有类都会被卸载。
以上是关于类卸载的触发条件以及示例解释的完整攻略。