方法区的垃圾回收

方法区的垃圾回收

  • 有人认为方法区(如HotSpot虚拟机中元空间或者永久代)是没有垃圾收集行为的,其实不然,Java虚拟机规范中堆方法区的约束是非常宽松的,提到过可以不要求虚拟机在方法区中实现垃圾收集,事实上也确实有未实现或未能完整实现方法区类型卸载的垃圾收集器存在(如JDK11时期的ZGC收集器就不支持类卸载)

  • 一般来说这个区域的回收效果比较难令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收有时又确实是必要的,以前Sun公司的bug列表中,曾出现若干严重的bug就是由于低版本的HotSpot虚拟机对此区域未完全回收而导致内存泄漏

  • 方法区的垃圾收集主要回收两部分内容:常量池中废弃的常量和不再使用的类型

  • 判定一个常量是否"废弃"还是相对简单,而要判定一个类型是否属于"不再被使用的类"的条件就比较苛刻了,需要同时满足下面三个条件

    • 该类的所有实例都已经被回收,也就是Java堆中不存在该类及其任何派生子类的对象
    • 加载该类的类加载器已经被回收,这个条件除非是经过精心设计的可替换类加载器的场景,如OSGI,Tomcat的重加载等,否则通常是很难达成的
    • 该类的Java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
  • Java虚拟机被允许对满足上述三个条件的无用类进行回收(只是被允许)

你可能感兴趣的:(jvm,java)