回收方法区
方法区主要回收的是那些东西?
废弃常量
无用的类
。
什么情况下会回收废弃常量?
- 回收废弃常量和回收Java堆中的对象十分类似。
- 以常量池中字面量(直接量)的回收为例,假如一个字符串"abc"已经进入了常量池中,但是当前系统没有任何一个String对象引用常量池的"abc"常量,也没有在其他地方引用这个字面量,如果此时发生GC并且有必要的话,这个"abc"常量会被系统清理出常量池。常量池中的其他类(接口)、方法、字段的符号引用也与此类似。
什么情况下,一个类才算无用的类?
判定一个类是否是"无用类"则相对复杂很多。类需要同时满足下面三个条件才会被算是"无用的类" :
- 该类
所有实例都已经被回收
(即在Java堆中不存在任何该类的实例) - 加载该类的
ClassLoader已经被回收
- 该类对应的
Class对象没有在任何其他地方被引用,无法在任何地方通过反射访问该类的方法
满足三种情况,无用的类一定会被回收吗?
JVM可以对同时满足上述3个条件的无用类进行回收,也仅仅是"可以"而不是必然。在大量使用反射、动态代理等场景都需要JVM具备类卸载的功能来防止永久代的溢出。