CMS(Concurrent Mark Sweep)垃圾回收器是专为老年代设计的一种垃圾回收算法,其目标是尽可能减少垃圾回收导致的程序暂停时间,特别适用于对响应时间有严格要求的应用场景。以下是CMS垃圾回收过程的详细步骤:
1. 初始标记(Initial Mark)
- STW(Stop-The-World)事件:首先触发一次短暂的全局暂停,仅标记出直接与GC Roots可达的对象以及年轻代晋升到老年代的存活对象。
- 这个阶段的目标是快速标记出直接关联对象,确保后续并发标记过程中不会遗漏这部分对象。
2. 并发标记(Concurrent Mark)
- 并发执行:在应用程序继续运行的同时,垃圾收集器启动多个线程并发进行标记工作,遍历堆中对象图,递归地标记所有可从已标记对象间接可达的对象。
- 增量更新(Incremental Update) :为了减少对应用程序的干扰,CMS可能会使用增量更新等技术,分批完成标记任务。
3. 并发预清理(Concurrent Preclean)
- 并发阶段:此阶段是为了处理并发标记过程中因用户线程继续运行而可能出现的对象引用关系变化,减少下一阶段的重标记工作量。
- 处理弱引用:CMS在此阶段可能还会处理弱引用(如SoftReference、WeakReference、PhantomReference等),避免它们在重标记阶段影响标记准确性。
4. 重标记(Remark)
- STW事件:再次触发一次全局暂停,重新扫描堆中可能在并发标记阶段发生变化的对象引用关系,修正并发标记期间因并发操作导致的标记错误。
- 此阶段通常比初始标记阶段稍长,但仍然力求保持较短的暂停时间。
5. 并发清理(Concurrent Sweep)
- 并发执行:在应用程序继续运行的同时,垃圾收集器并发清理已标记为“死亡”的对象,释放其占用的内存空间。
- 位图记录:CMS可能会使用位图或其他数据结构记录已清理区域,便于快速分配内存。
6. 并发重置(Concurrent Reset)
- 恢复数据结构:此阶段同样是并发执行,垃圾收集器重置内部数据结构和状态,为下一轮垃圾回收做准备。
特点与缺点:
-
优点:
- 低停顿:大部分工作(标记、预清理、清理、重置)并发进行,显著减少了垃圾回收导致的程序暂停时间。
- 适应高并发场景:适用于对响应时间敏感、无法接受长时间停顿的应用。
-
缺点:
- 内存碎片:由于采用标记-清除算法,CMS在清理过程中不会进行内存整理,可能导致老年代内存碎片化,影响大对象分配和长期性能。
- CPU资源消耗:并发标记和清理阶段需要消耗额外的CPU资源,可能会影响应用程序的吞吐量。
- 浮动垃圾:由于并发清理阶段与用户线程同时运行,这段时间内新产生的不可达对象(即“浮动垃圾”)可能来不及在这次回收中清理,需要等到下一次回收周期。
- STW次数与时长:虽然总体上STW时间较短,但仍然存在两次STW事件(初始标记和重标记),且重标记阶段可能因并发操作的影响而有所延长。