步骤:
- 使用 URLClassLoader(属于自定义类加载器)加载 jar 中的 class 文件;
- 消除引用:
1.classLoader=null; 2.clazz=null; 3.instance=null;
; - 调用 System.gc() 尝试 gc;
- 添加 jvm 参数,查看加载、卸载情况;
public static void main(String[] args) throws Exception {
String jarPath = "/Users/zhouhao/Desktop/workspace/mvnprojects/java-demos/target/dms-1.0-SNAPSHOT.jar";
URL[] urls = new URL[]{new URL("file:" + jarPath)};
URLClassLoader urlClassLoader = new URLClassLoader(urls);
// 遍历 jar 包内的所有文件,如果判断是 .class 文件,则尝试加载
try (JarFile jarFile = new JarFile(new File(jarPath))) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String name = jarEntry.getName();
System.out.println("= entryName: " + name);
if (!jarEntry.isDirectory() && name.endsWith(".class")) {
try {
Class<?> c = urlClassLoader.loadClass(name.substring(0, name.length() - 6).replaceAll("/", "."));
System.out.println("* urlClassLoader has load: " + c);
} catch (Throwable e) {
System.err.println("! throwable one: " + e.getClass().getName() + ", " + e.getMessage());
}
}
}
}
System.out.println("---------------");
//打印 ...AppClassLoader...,说明 urlClassLoader 是自定义,可进行类卸载
System.out.println(urlClassLoader.getParent());
System.out.println("----- class unload ---------");
urlClassLoader = null;
System.gc();
System.in.read();
}
添加 jvm 参数
-XX:+TraceClassLoading -XX:+TraceClassUnloading
部分日志(注意:其中 im.eg.ut.MobileUtil
类来自 jar 包)
...
[Loaded im.eg.ut.MobileUtil from file:/Users/zhouhao/Desktop/workspace/mvnprojects/java-demos/target/dms-
---------------
sun.misc.Launcher$AppClassLoader@18b4aac2
----- class unload ---------
[Unloading class im.eg.ut.MobileUtil 0x00000007c0061028]
...