Java教程

java类加载子系统之类的卸载

本文主要是介绍java类加载子系统之类的卸载,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 前言
    • 一、描述
    • 二、图例
    • 三、方法区的垃圾回收


前言

语雀地址:https://www.yuque.com/yangxiaofei-vquku/wmp1zm/dmz2gd

一、描述

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

二、图例

下图为针对Sample的可达性分析引用图
在这里插入图片描述

根据可达性分析算法分析如果要让Sample类卸载即让GCROOT和堆里的Sample.class实例没有引用关系,由于③、⑤不可能断,所以只能断掉引用①、②、③,此时Sample类和方法区里的Sample元数据将一起被回收,卸载。(MyClassLoader类不会被回收,因为MyClassLoader.class的引用还被系统类加载器持有,最多堆里的MyClassLoader实例被回收)

三、方法区的垃圾回收

方法区的垃圾收集主要回收两部分内容:常量池中废弃的常量和不在使用的类型(instanceKlass)。
Hotspot虚拟机对常量池的回收策略是很明确的,只要常量池中的常量没有被任何地方引用,就可以被回收。
判定一个常量是否“废弃”还是相当简单的,而要判定一个类型是否数据“不再被使用的类”的条件就比较苛刻了。同时需要满足下面三个条件:

  1. 该类所以的实例都已经被回收,也就是java堆中不存在该类及其任何派生子类的实例。
  2. 加载该类的类加载器实例已经被回收,这个条件除非是经过精细设计的课替换类加载器的场景,如OSGi、JSP的重加载等,否则通常很难达成的。
  3. GCROOT没有任何引用可以访问到该类对应的java.lang.Class对象实例,无法在任何地方通过反射访问该类。

再加上方法区只有在full_gc的时候才会触发,本身频率就很低,所以一个已加载的类型被卸载的几率很小,被卸载的时间也不确定。所以我们平时开发代码时,不应该对虚拟机的类型卸载做任何假设的前提下,来实现系统中的特定功能。

这篇关于java类加载子系统之类的卸载的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!