对于不可能再被任何途径使用的对象,认为它应该被回收。通过分析对象引用,有两种判断对象是否可以回收的算法。
引用计数算法(Reference Counting) 在对象中添加一个引用计数器,当计数器为零代表可回收,当计数器+1代表有一个地方引用了它。 优点: 原理简单,判定效率高。 缺点: 如果存在两个对象互相循环引用,除此之外再无其他途径访问这两个对象。那么应该都被回收的这两个对象却永远都不会被回收。可达性分析算法(Reachability Analysis) 通过一系列称为“GC Roots”的根对象作为起始节点集,如果从GC Roots到某个对象不可达时,就认为该对象可回收。 该算法就很好地解决了引用计数算法的互相循环引用的问题。强引用: 只要对象存在强引用,就永远不会被回收。如直接赋值。 软引用: 只有在内存将要溢出时才会回收这些对象。使用SoftReference类可以实现软引用。 弱引用: 只要发生GC就会被回收。使用WeakReference类可以实现弱引用。 虚引用: 无法通过虚引用来获得一个对象实例,为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。使用PhantomReference类可以实现虚引用。
标记需要回收(存活)的对象,标记完成后,统一回收掉所有被标记的对象(回收掉未被标记的对象)。 优点: 实现简单,速度快。 缺点: 1、效率不稳定:标记和清除两个过程的执行效率,随着对象数量增长而降低。 2、内存碎片化:产生大量不连续的内存碎片,导致无法立即分配较大对象(即使可用内存空间足以分配)
将内存按容量分为大小相等的两块,每次只使用其中的一块。当这一块内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。 优点: 实现简单,运行高效。 缺点: 空间浪费。
和标记清除相比会将所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存。 优点: 相较于标记清除算法有着更高的吞吐量,解决了内存碎片化的问题。 缺点: 执行效率较低。