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();        }    }}