MST

星途 面试题库

面试题:Java虚拟机运行时数据区中方法区的垃圾回收

在Java虚拟机运行时数据区的方法区中,垃圾回收主要针对哪些内容进行?触发方法区垃圾回收的条件是什么?方法区垃圾回收相较于堆内存垃圾回收有哪些难点和特殊之处?
14.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

方法区垃圾回收针对的内容

  1. 废弃的常量:例如字符串常量池中,若某个字符串常量不再被任何地方引用,就可能成为被回收的对象。比如通过 intern() 方法创建的字符串常量,如果没有其他强引用指向它,可能被回收。
  2. 不再使用的类型:当类加载器被回收,且该类的所有实例都已被回收,同时该类对应的 Class 对象不再被任何地方引用时,该类的相关元数据(如类的字段、方法、常量池等信息)就可能被回收。

触发方法区垃圾回收的条件

  1. 对于废弃常量:当常量池中指向常量的引用都被释放,且该常量没有被任何其他地方引用时,便满足了回收条件。
  2. 对于不再使用的类型:需要同时满足以下三个条件:
    • 该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。
    • 加载该类的 ClassLoader 已经被回收。在一些框架使用自定义类加载器时,如果类加载器生命周期结束且不再被引用,就可能满足此条件。
    • 该类对应的 java.lang.Class 对象没有在任何地方被引用,即无法通过反射访问该类的方法等。

方法区垃圾回收相较于堆内存垃圾回收的难点和特殊之处

  1. 判定条件复杂:堆内存中对象的存活判定相对简单,主要基于可达性分析算法,只要对象到 GC Roots 不可达就可能被回收。而方法区中类型的回收需要同时满足多个条件(如上述提到的类相关回收条件),判定更为复杂。
  2. 回收频率低:方法区中的数据相对稳定,不像堆内存中的对象频繁创建和销毁。例如,类的元数据一旦加载进方法区,在应用运行期间通常不会轻易变化,所以垃圾回收触发频率远低于堆内存。
  3. 影响范围大:方法区回收类元数据等信息,如果误回收正在使用的类,会导致严重的程序错误,如运行时类找不到等问题。相比之下,堆内存中回收错误对象通常只会影响局部业务逻辑。