引用计数法
存在循环引用问题。
Redis是通过循环引用判断对象是否死亡的。
可达性分析
从GC Roots向下不可达时,证明此对象是不可能再使用的。
GC Roots的对象:
- JVM栈中的对象。
- 本地方法栈(native方法)中的对象。
- 方法区中静态引用的对象,如static final修饰的对象。
- 方法区中常量引用的对象,如字符串常量池里的引用。
- 被同步锁(synchronized)持有的对象。
- …
引用类型
传统的“引用”定义:如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称该reference数据是代表某块内存、某个对象的引用。
传统的定义使得对象只有“被引用”和“未被引用”两种状态,具有局限性。
比如想描述这样的对象就无能为力:内存空间还足够时,能保存在内存中,如果内存空间进行垃圾回收之后仍然紧张,那就可以抛弃这些对象。
强引用:只要存在强引用,垃圾回收器就不会回收。
软引用:GC后如果内存够了就不会回收,如果内存还不够就会回收。
弱引用:只要发生GC就被回收。
虚引用:为一个对象设置虛引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知(回收跟踪)。
finalize方法
在可达性分析中判定为不可达对象之后,还会看此对象有没有finalize()方法,有则执行。
finalize()只会执行一次,第二次GC时不会执行,对象会被直接回收。
不推荐使用,用try-finally更好。
回收方法区
方法区的回收主要针对两部分内容:废弃的常量和不再使用的类型。
回收常量:该常量不再被引用。
回收类型:条件:
- 该类所有的实例已经被回收,即堆中不存在该类及其任何派生子类的实例;
- 加载该类的类加载器已经被回收;
- 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。