package study;
import java.net.URL;
import java.net.URLClassLoader;
/*
由Java虚拟机自带的类加载器所加载的类,在虚拟机的生命周期中,始终不会被卸载,
Java虚拟机自带的类加载器包括根类加载器、扩展类加载器和系统类加载器。
Java虚拟机本身会始终引用这些类加载器,而这些类加载器则会始终引用它们所加载的类的Class对象,
因此这些Class对象始终是可触及的。
由用户自定义的类加载器加载的类是可以被卸载的。
jvm参数-verbose:class 即可看到类的加载和卸载信息
*/
/*
卸载类满足的条件
1、class所有实例被回收
2、class类没有别引用
3、class的加载器实例被回收
*/
public class StudyMain {
public static void main(String[] args) throws Exception {
new StudyMain().solve();
Thread.sleep(5000);
System.gc();
Thread.sleep(5000);
}
public void solve() {
/*
path不以’/'开头时,默认是从此类所在的包下取资源;
path以’/'开头时,则是从ClassPath根下获取;
this.getClass().getResource("").getPath();
*/
// 这个路径 <= appClassLoader所负责的路径,因为双亲委托的机制
String path = "/D:/gitHome/asmStudy/target/classes/";
try {
// 这里一定要加file: 表示协议
ClassLoader loader1 = new URLClassLoader(new URL[]{new URL("file:" + path)});
// 类名要写全
Class t = loader1.loadClass("instrumentation.TransClass");
t = null;
loader1 = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
当类加载器重写了finalize
package study;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class MyClassLouder extends ClassLoader {
public static void main(String[] args) throws Exception {
String path = "D:\\Users\\YEZHENGWU839\\Desktop\\xiaoxi\\";
MyClassLouder other = new MyClassLouder(path, "other");
Class.forName("MethodAccessor.TestLoad", true, other);
other = null;
Thread.sleep(5000);
System.gc();
Thread.sleep(5000);
// 第一次gc卸载不掉类是因为finalize线程优先级比较低 所以回收的时候
// other的 finalize 对象还没有被finalize线程清理
// 所以other并没有回收,所以类也就卸载不了
System.out.println("第一次 gc 结束 第二次开始");
System.gc();
Thread.sleep(5000);
}
private String classpath;
private String name;
// 重写finalize方法 一般不重写这个 影响gc
@Override
protected void finalize() throws Throwable {
System.out.println("MyClassLoader finalize");
}
public MyClassLouder(String classpath, String name) {
this.classpath = classpath;
this.name = name;
}
public MyClassLouder(String classpath, String name, ClassLoader parent) {
super(parent);
this.classpath = classpath;
this.name = name;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] bin = Files.readAllBytes(Paths.get(classpath + name.replace(".", "/") + ".class"));
return defineClass(bin, 0, bin.length);
} catch (IOException e) {
throw new ClassNotFoundException();
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。