引用计数法

  • 问题1: 无法处理循环引用的情况

  • 问题2: 都要伴随着加减引用计数操作,对性能有一定的影响

名词解释

可达对象

通过根对象进行引用搜索, 最终可以达到的对象

不可达对象

通过根对象进行引用搜索,最终没有被引用到的对象

新生代

存放年轻对象的堆空间.年轻对象指刚刚创建的, 或者经历垃圾回收次数不多的对象.

老年代

存放老年对象的堆空间.老年对象指经历多次垃圾回收依然存活的对象.

标记清除(Mark-Sweep)

  • 第一阶段: 首先通过根节点, 标记所有从根节点开始的可达对象.因此未被标记的对象就是未被引用的垃圾对象.

  • 第二阶段: 清除所有未被标记的对象.

最大的问题: 空间碎片.

复制算法

将原有的内存空间分成两块, 每次只使用其中一块, 在垃圾回收时, 将正在使用的内存中的存活对象复制到未使用的内存块中,之后清除正在使用的内存块中的所有对象, 交换两个内存的角色, 完成垃圾回收.

最大问题: 可用内存减半.

在Java新生代串行垃圾回收器中,使用了复制算法的思想.如其中的 fromto 空间.

标记压缩算法(Mark-Compact)

老年代的一种垃圾回收算法.

  • 第一阶段: 标记

  • 第二阶段: 压缩

  • 第三阶段: 清理

最终效果等同于标记清除算法执行完成后, 再进行一次内存碎片整理.

分代算法

  • 新生代: 复制算法

  • 老年代: 标记压缩算法 或 标记清除算法

分区算法

引用类型

强引用

  • 强引用可以直接访问目标对象

  • 强引用所指向的对象在任何时候都不会被系统回收,虚拟机宁愿抛出OOM异常,也不会回收强引用所指向对象

  • 强引用可能导致内存泄漏

例如: Object o = new Ojbect(), o 就是强引用.

软引用

  • 一个对象只持有软引用, 那么当堆空间不足时, 就会被回收. 软引用使用java.lang.ref.SoftReference类实现.

弱引用

  • GC时,只要发现弱引用,就会回收.使用java.lang.ref.WeakFeference

软引用 和 弱引用 都非常适合来保存那些可有可无的缓存数据.

虚引用

  • 和没有引用几乎一样.试图get()时,总是会失败. 并且必须要和队列一起使用, 它的作用在于跟踪垃圾回收过程.