类的命名空间详解:

在上一次【https://www.cnblogs.com/webor2006/p/9108301.html】最后实验中有一个违背咱们理解的,这里回顾一下:

也就是说,"某一个类对应的class文件只能被加载一次",这是有一个大前提的,该前提就是"该类加载器必须是在同一个命名空间里",如果在不同的命名空间同一个类的字节码文件是可以被加载多次的,那带着命名空间的概念咱们再来解析一下上面的输出:

在要加载的MyTest1字节码文件从编译工程中删除之后,由于都会由咱们自己所编写的自定义类加载器MyTest16所加载,而由于是两个不同类加载器,虽说类加载器的类型都属于自定义的MyTest16,这里可以增加一个日志来直观的体会一下:

编译运行:

那如果不将工程中编译的MyTest1字节码文件删掉其运行结果又是:

搞清楚了命名空间概念之后,下面继续基于该程序进行改造,前提还是MyTest1的字节码文件已经从工程中被删掉了,改造如下:

那结果是什么呢?

其实这个细节在loadClass()方法中已经有说明:

另外还需要注意一个细节,这里先回顾一下类加载器的层次体系:

虽说图中表达的是一种树形的结构,其实是一种包含关系,子加载器包含父加载器的一个引用,其实这种引用关系还可以进一步延伸,以咱们的这个例子为例:

下面再来定义一个类加载器:

重新编译,此时MyTest1的字节码文件已经在工程当中了,运行:

那接下来将MyTest1的字节码文件从工程中删掉,那这次结果又会有啥变化呢?

好,继续再修改:

编译运行,此时MyTest1的字节码文件存于工程当中了:

那如果将MyTest1的字节码文件给删掉其结果又会如何呢?

以上通过这么详细的实验是不是对类的双亲委托以及命名空间的概念有了非常深刻的认识。

类的卸载详解与jvisualvm使用:

  • 当MySample类被加载、连接和初始化后,它的生命周期就开始了。当代表MySample类的Class对象不再被引用,既不可触及时,Class对象就会结束生命周期,MySample类在方法区内的数据也会被卸载,从而结束Sample类的生命周期。
  • 一个类何时结束生命周期,取决于代表它的Class对象何时结束生命周期。
  • 由Java虚拟机自带的类加载器所加载的类,在虚拟机的生命周期中,始终不会被卸载。前面已经介绍过,Java虚拟机自带的类加载器包括根类加载器、扩展类加载器和系统类加载器。Java虚拟机本身会始终引用这些类加载器。而这些类加载器则会始终引用它们所加载类的类的Class对象,因此这些Class对象始终是可触及的。【言外之意就是说三大系统类加载器加载的Class对象是无法被卸载的】
  • 由用户自定义的类加载器所加载的类是可以被卸载的。【如咱们自定义的MyTest16加载器所加载的类】
  • 运行以上程序时,Sample类由loader1加载。在类加载器的内部实现中,用一个Java集合来存放所加载类的引用。另一方面,一个Class对象总是会引用它的类加载器。调用Class对象的getClassLoader()方法,就能获取它的类加载器,由此可见,代表Sample类的Class实例与loader1之间为双向关联关系。一个类的实例总是引用代表这个类的Class对象,在Object类中定义了getClass()方法,这个方法返回代表对象所属类的Class对象的引用。此外,所有的Java类都有一个静态属性class,它引用代表这个类的Class对象。

上面一大堆的理论有木有实验能清晰的看到类被卸载的呢?下面就来实验一下:

那如何能看到类的卸载信息呢?这时就需要加一个JVM的运行参数"-XX:+TraceClassUnloading",如下:

再次运行:

那如何来模拟呢,看下面:

那:

试试不加:

那如果就想不加那三断置null的语句也能看到类被卸载的信息,如何搞呢?

其实还可以利用jvisualvm小工具也能查看到类被卸载的记录,代码还是先还原,如下:

先运行jvisualvm:

然后再启动咱们的测试程序:

此时进程信息就会出现在jvisualvm工具之上,如下:

然后选择它打开具体的监视信息:

关于jvisualvm的其它功能待以后学习慢慢挖掘~

类的命名空间与卸载详解及jvisualvm使用的更多相关文章

  1. CSS中伪类及伪元素用法详解

    CSS中伪类及伪元素用法详解   伪类的分类及作用: 注:该表引自W3School教程 伪元素的分类及作用: 接下来让博主通过一些生动的实例(之前的作业或小作品)来说明几种常用伪类的用法和效果,其他的 ...

  2. StringUtils类API及使用方法详解

    StringUtils类API及使用方法详解 StringUtils方法概览 判空函数 1)StringUtils.isEmpty(String str) 2)StringUtils.isNotEmp ...

  3. 第15.10节 PyQt(Python+Qt)入门学习:Qt Designer可视化设计界面组件与QWidget类相关的组件属性详解

    PyQt学习有阵子了,对章节的骨架基本考虑好了,准备本节就写组件的属性的,结果一是日常工作繁忙,经常晚上还要加班,二是Qt的组件属性很多,只能逐一学习.研究和整理,花的时间有点长,不过终于将可视化设计 ...

  4. <JVM中篇:字节码与类的加载篇>03-类的加载过程(类的生命周期)详解

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  5. Object类、包装类、内部类详解

    1.Object类 1.概念: 1.1 所有类在创建时都默认继承了java.lang.Object 1.2 所有类对象都可以声明为类对象的引用 Object ob1=new String(); Obj ...

  6. Kotlin——从无到有系列之中级篇(四):面向对象的特征与类(class)继承详解

    如果您对Kotlin很有兴趣,或者很想学好这门语言,可以关注我的掘金,或者进入我的QQ群大家一起学习.进步. 欢迎各位大佬进群共同研究.探索 QQ群号:497071402 进入正题 在前面的章节中,详 ...

  7. java中ReentrantLock类的详细介绍(详解)

    博主如果看到请联系小白,小白记不清地址了 简介 ReentrantLock是一个可重入且独占式的锁,它具有与使用synchronized监视器锁相同的基本行为和语义,但与synchronized关键字 ...

  8. mybatis中的mapper接口文件以及example类的实例函数以及详解

    ##Example example = new ##Example(); example.setOrderByClause("字段名 ASC"); //升序排列,desc为降序排列 ...

  9. [Java]Java类和对象内存分配详解

    描述 代码说明: 一.当Person p1 = new Person();第一次被调用时需要做两件事: 1.先判断类加载器是否加载过Person类,如果没有则加载到Person类型到方法区 2.在堆中 ...

随机推荐

  1. OPC Utgard的数据访问方式

    1.同步读取某个点位的值 Item项的read()方法 Server server = new Server(BaseConfiguration.getCLSIDConnectionInfomatio ...

  2. 【编程开发】C语言中随机数rand使用注意事项

    [编程开发]C语言中随机数rand使用注意事项 标签: [编程开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:随机数在编程开发中非常重要,以C语 ...

  3. kettle下载地址

    kettle 4.4和4.2 版本是好的,版本6.6和8.2 版本有bug Kettle下载和安装: 1.官网各个版本下载地址:https://sourceforge.net/projects/pen ...

  4. Pandas 读取超过 65536 行的 Excel 文件

    Excel 文件的格式曾经发生过一次变化,在 Excel 2007 以前,使用扩展名为 .xls 格式的文件,这种文件格式是一种特定的二进制格式,最多支持 65,536 行,256 列表格.从 Exc ...

  5. (十六)JDBC 处理大数据

    目录 前言: 基本概念 对于Mysql的Text类型 流地址的写法 blob类型数据 备注 前言: 在实际开发中,程序需要把 大文本或二进制 数据保存到数据库中: 实际上,我们并不存储大的数据到数据库 ...

  6. C++ Primer练习题day2

    /* 1.7略 1.8 /* 指出不合法的语句: std::cout<<"/"; std::cout<<"*/ "; std::cout ...

  7. python中sort和sorted用法的区别

    Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列 一,最简单的排序 1.使用sort排序 my_list = [3 ...

  8. Docker 容器学习笔记

    Docker 诞生于2013年,最初发起者是dotCloud公司.Docker自开源后受到广泛的关注和讨论,目前已有多个相关项目逐渐形成了围绕Docker容器的生态体系,由于Docker在业界造成的影 ...

  9. java Lesson08总结

    package com.xt.java.FirstExciple.oop; public class NokiaPhone {  //成员变量 String name="np001" ...

  10. ADO.NET连接数据库增删查改创建公用类

    顺序如下:再web.config中添加数据库的用户名和密码 创建公用类. //添加进web.config中的账号和密码 /*<connectionStrings> <add name ...