JVM学习笔记18——类的命名空间与卸载详解及jvisualvm的使用
发布日期:2021-06-29 01:18:54 浏览次数:2 分类:技术文章

本文共 2952 字,大约阅读时间需要 9 分钟。

MyTest16 loader2 = new MyTest16(loader1,"loader2");

将loader1作为loader2的父类加载器,输出如下:

loader2会委托loader1去加载MyTest1,在第一次已经被加载过,所以第二次不再重复加载

保持MyTest1.class删除,增加loader3

public static void main(String[] args) throws Exception{        MyTest16 loader1 = new MyTest16("loader1");        // 在本地建立指定目录,然后删掉idea编译的MyTest1,可以发现findClass执行了        loader1.setPath("D:\\workspace\\");        // loader1.setPath("/d/workspace/jvm_lecture/target/classes/");        Class
clazz = loader1.loadClass("com.yshuoo.jvm.classloader.MyTest1"); System.out.println("class: " + clazz.hashCode()); Object object = clazz.newInstance(); System.out.println(object); System.out.println("************"); MyTest16 loader2 = new MyTest16(loader1,"loader2"); loader2.setPath("D:\\workspace\\"); Class
clazz2 = loader2.loadClass("com.yshuoo.jvm.classloader.MyTest1"); System.out.println("class: " + clazz2.hashCode()); Object object2 = clazz2.newInstance(); System.out.println(object2); System.out.println("************"); MyTest16 loader3 = new MyTest16("loader3"); loader3.setPath("D:\\workspace\\"); Class
clazz3 = loader3.loadClass("com.yshuoo.jvm.classloader.MyTest1"); System.out.println("class: " + clazz3.hashCode()); Object object3 = clazz3.newInstance(); System.out.println(object3); }

可以看出,loader2和loader1在同一个命名空间,loader3和loader1,2不在同一个命名空间,所以loader3会自己加载

MyTest16 loader3 = new MyTest16(loader2,"loader3");

将loader2做为loader3的父类加载器

由于双亲委托模型这三个类加载器加载的都是同一个对象

类的卸载:

  • 当MySample类被加载、连接和初始化后,它的生命周期就开始了。当代表MySample类的Class对象不再被引用,即不可触及时,Class对象就会结束生命周期,MySample类在方法区内的数据也会被卸载,从而结束MySample类的生命周期
  • 一个类何时结束生命周期,取决于代表它的Class对象何时结束生命周期

由Java虚拟机自带的加载器所加载的类,在虚拟机的生命周期中,始终不会被卸载。

由用户自定义的类加载器所加载的类是可以被卸载的。

保持MyTest1删除,将loader1指向新的类加载器,在运行时加参数-XX:+TraceClassUnloading

public static void main(String[] args) throws Exception{        MyTest16 loader1 = new MyTest16("loader1");        // 在本地建立指定目录,然后删掉idea编译的MyTest1,可以发现findClass执行了        loader1.setPath("D:\\workspace\\");        // loader1.setPath("/d/workspace/jvm_lecture/target/classes/");        Class
clazz = loader1.loadClass("com.yshuoo.jvm.classloader.MyTest1"); System.out.println("class: " + clazz.hashCode()); Object object = clazz.newInstance(); System.out.println(object); System.out.println("************"); // 为了验证被卸载,将所有引用都去掉 loader1 = null; clazz = null; object = null; System.gc(); loader1 = new MyTest16("loader1"); // 在本地建立指定目录,然后删掉idea编译的MyTest1,可以发现findClass执行了 loader1.setPath("D:\\workspace\\"); // loader1.setPath("/d/workspace/jvm_lecture/target/classes/"); clazz = loader1.loadClass("com.yshuoo.jvm.classloader.MyTest1"); System.out.println("class: " + clazz.hashCode()); object = clazz.newInstance(); System.out.println(object); }

可以看出确实卸载掉了第一个loader1

转载地址:https://blog.csdn.net/yshuoo/article/details/116522014 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:JVM学习笔记19——自定义类加载器在复杂类加载情况的运行分析
下一篇:JVM学习笔记17——类加载器双亲委托机制实力剖析

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月29日 23时54分32秒