一、标记-清除算法(Mark-Sweep)

算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回 收所有未被标记的对象.
主要缺点有两个: 第一个是执行效率不稳定,如果Java堆中包含大量对象,而且其中大部分是需要被回收的,这时必须进行大量标记和清除的动作,导致标记和清除两个过程的执行效率都随对象数量增长而降低;第二个是内存空间的碎片化问题,标记、清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致当以后在程序运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作.
image.png


二、标记-复制算法

复制算法把内存分成两块完全相同的区域,每次使用其中一块,当一块使用完了,就把这块上还存活的对象拷贝到另外一块,然后把这块清除掉。
优点:实现简单,运行高效,不用考虑内存碎片问题
缺点:内存浪费
运用:JVM实现中,是将新生代内存分为一块较大的Eden区和两块较小的Survivor空间,每次使用Eden和一块Survivor,回收时把存活对象复制到另外一块Survivor。HotSpot默认的Eden和Survivor比是8:1,也就是每次使用90%的新生代空间;如果Survivor空间不够,就要依赖老年代进行分配担保,把放不下的对象直接进入老年代。
image.png

三、标记-整理算法

  1. <br />标记-复制算法在对象存活率较高时就要进行较多的复制操作,效率将会降低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般使用标记整理算法。 <br />标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存,规避内存碎片问题。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/558192/1621704161146-57897e65-8a59-4cd8-950f-b893543101fa.png#clientId=u74b7bd7d-7808-4&from=paste&height=511&id=ue155f79d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1022&originWidth=1638&originalType=binary&size=627875&status=done&style=none&taskId=u65d45e54-9288-4c2d-8b1b-c20e692c0b6&width=819)<br /> <br /> <br /> <br /> <br /> <br />
  2. <br /> <br /> <br /> <br /> <br /> <br />