天天看点

深入理解java虚拟机学习笔记(5)——垃圾收集算法垃圾收集算法一、分代收集理论二、标记-清除算法三、标记-复制算法四、标记-整理算法

垃圾收集算法

垃圾收集算法可划分为“引用计数式垃圾收集”和“追踪式垃圾收集”两大类,这两类也被称为“直接垃圾收集”和“间接垃圾收集”。以下全为“追踪式垃圾收集”。

目录

  • 垃圾收集算法
  • 一、分代收集理论
  • 二、标记-清除算法
  • 三、标记-复制算法
  • 四、标记-整理算法

一、分代收集理论

  • 弱分代假说:绝大多数对象都是朝生夕灭的。
  • 强分代假说:熬过越多次垃圾收集过程的对象就越难以消亡。
  • 跨代引用假说:跨代引用相对于同代引用来说占极少数。

前两个假说奠定了常用垃圾收集器的设计原则:收集器应该将Java堆划分出不同的区域,然后将回收对象依据其年龄(年龄即熬过垃圾收集过程的次数)分配到不同的区域之中存储。

为什么要引入第三条经验法则:如果要进行一次只局限于新生代区域内的收集,但新生代中你的对象是完全有可能被老年代所引用的,为了找出存活的对象,就需要额外遍历整个老年代中的所有对象,这会给内存回收带来很大的性能负担。

部分收集(Partial GC):指目标不是完整收集整个Java堆的垃圾收集。

  • 新生代收集(Minor GC/Young GC):指目标只是新生代的收集。
  • 老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集。
  • 混合收集(Mixed GC):指目标是收集整个新生代以及部分老年代的垃圾收集。

整堆收集(Full GC):收集整个Java堆和方法区的垃圾收集。

二、标记-清除算法

标记-清除(Mark-Sweep)算法分为“标记”和“清除”两个阶段:首先标记出所有存活的对象,统一回收所有未被标记的对象。

缺点:

  • 执行效率不稳定
  • 内存空间的碎片化问题
深入理解java虚拟机学习笔记(5)——垃圾收集算法垃圾收集算法一、分代收集理论二、标记-清除算法三、标记-复制算法四、标记-整理算法

如图,深色为可回收部分,当回收后,深色部分变为未使用状态;回收后未使用区块有很多不连续的,即产生了大量的不连续的内存碎片,以后如果程序需要分配较大对象时无法找到足够的连续内存,就要提前触发垃圾收集动作。

三、标记-复制算法

标记-复制(Mark-Copy)算法将可用内存按容量划分为大小相等的两块,每次只是用其中一块。当这一块的内存用完了,就将还存活的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

优点:

  • 分配内存时不需要考虑空间碎片的复杂情况,只需要按顺序分配即可

缺点:

  • 如果大多数对象都是存活的,会产生大量内存间复制的开销
  • 该复制短发将内存缩小为原来的一半,空间浪费过大
深入理解java虚拟机学习笔记(5)——垃圾收集算法垃圾收集算法一、分代收集理论二、标记-清除算法三、标记-复制算法四、标记-整理算法

四、标记-整理算法

标记-整理(Mark-Compact)算法,先对对象进行标记,然后所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存。

优点:

  • 内存分配时较为简单,由于内存分配和访问相比垃圾收集的频率要高得多,因此不移动对象总吞吐量会高一些。

缺点:

  • 内存回收更为复杂
  • 移动存活对象停顿时间会更长(这个停顿是全程暂停用户应用程序)
    深入理解java虚拟机学习笔记(5)——垃圾收集算法垃圾收集算法一、分代收集理论二、标记-清除算法三、标记-复制算法四、标记-整理算法