JVM垃圾回收的三种算法(五)

标记-清除算法(最基础)

算法分为:“标记”,“清除”两个阶段,首先标记处所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以标记存活的对象,统一回收未被标记的对象。
缺点:

  1. 执行效率不稳定,如果Java堆中包含大量对象,而且其中大部分是需要被回收的,就必须进行大量的标记和清除动作,造成标记和清除两个过程执行效率都随对象的增多而降低。
  2. 内存碎片化,标记,清除之后会产生大量不连续的内存碎片,空间碎片过多会导致程序运行中如果需要分配较大空间是无法找到足够的连续的内存空间而不得不提前触发一次垃圾收集动作。

标记-复制法

解决标记-清除法面对大量回收对象执行效率低的问题。
**方法:**将回收区域分区,其中某几个区存放对象,剩余的区保留,回收时将存活的对象分配到保留分区中,已用过的分区一次清理掉。
分配过程中不用担心内存碎片问题,只要移动堆顶指针,按顺序分配即可。
**优点:**简单,高效
**缺点:**保留分区不应过大,否则造成空间浪费。
Appel式回收: HotSpot虚拟机中的Serial,ParNew等新生代收集器采用这种策略设计新生代的内存布局。
做法:把新生代分为一个较大空间的Eden和两个较小空间的Survivor空间。每次分配只使用Eden和一块Survivor,发生垃圾收集时,将仍存活的对象分配到另一个Survivor空间中,清理掉Eden和已用过的Survivor空间。
HotSpot虚拟机默认Eden和Survivor的大小比为8:1。Eden为80%,Survivor为10%,用10%存放仍存活的对象可能不够(概率罕见),所以Appel式回收设计了一个“逃生门”,当Survivor空降不足容纳一次Minor GC后存活的对象是,就需要依赖其他内存区域(多数为老年代)进行分配。

标记-整理算法

使用标记-整理算法回收老年代,标记过程与标记-清除算法一样,但是不同为标记-整理算法不直接对可回收对象进行清理,而是让所有存活的对象想内存空间一端移动,然后直接清理掉边界以外的内存。
标记-清除算法与标记-整理算法本质差异;前者是一种非移动式的回收算法,后者是移动式的。
移动对象必须全程暂停用户的应用程序才能进行,操作极为负重。不移动对象又会造成,内存碎片,如果通过“分区空闲分配链表”来解决,会直接影响程序的吞吐量。移动与不移动都存在弊端。
不移动内存分配会更复杂,移动内存回收会更复杂,从垃圾收集时间来看,不移动对象停顿时间会更短,甚至不需要停顿,但从整个程序的吞吐量看,移动对象更划算。
HotSpot虚拟机中关注吞吐量的Parallel Scavenge收集器是基于标记-整理法的,而低延迟的CMS收集器是基于标记-清除法的。

猜你喜欢

转载自blog.csdn.net/weixin_43663421/article/details/109260406