深入解析:GC 算法的种类及垃圾收集器

主要算法

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

标记-清除算法是最基础的垃圾回收算法,分为标记和清除两个阶段。标记阶段遍历所有可达对象并标记,清除阶段回收未被标记的对象内存。适用于内存碎片不敏感的场景,如早期Java虚拟机。缺点是会产生内存碎片,可能引发频繁的GC。

复制算法(Copying)

复制算法将内存分为两块,每次只使用一块。当一块内存用完时,将存活对象复制到另一块,并清空当前块。适用于对象存活率低的场景,如新生代垃圾回收。优点是高效无碎片,但内存利用率仅50%。

标记-整理算法(Mark-Compact)

标记-整理算法在标记-清除的基础上增加了整理阶段,将存活对象向一端移动,然后清理边界外的内存。适用于老年代回收,避免内存碎片问题。缺点是移动对象成本高,适合对象存活率高的场景。

分代收集算法(Generational)

分代收集算法根据对象生命周期将堆分为新生代和老年代,针对不同代采用不同算法(如新生代用复制算法,老年代用标记-整理)。适用于大多数现代语言运行时(如Java、.NET),能平衡停顿时间和吞吐量。

垃圾收集器类型

串行收集器(Serial GC)

  • 特点:单线程STW(Stop-The-World),简单高效。
  • 适用场景:客户端程序或小内存服务端,但停顿时间较长。

通过以下JVM参数启用:

-XX:+UseSerialGC

并行收集器(Parallel GC)

  • 特点:多线程并行执行Minor和Full GC,吞吐量优先。
  • 适用场景:计算密集型任务(默认JDK8的收集器)。

启用参数:

-XX:+UseParallelGC

调整线程数和目标停顿时间:

-XX:ParallelGCThreads=N
-XX:MaxGCPauseMillis=time_ms

并发标记清除收集器(CMS)

  • 目标:减少Full GC停顿时间。(JDK5引入,JDK9弃用,JDK14删除)
  • 流程
    1. 初始标记(STW):标记根直接关联对象。
    2. 并发标记:标记所有可达对象(与用户线程并行)。
    3. 重新标记(STW):修正并发期间的变动。
    4. 并发清除:清理垃圾(与用户线程并行)。
  • 缺点:内存碎片、CPU资源竞争。启用参数:
-XX:+UseConcMarkSweepGC

调整并发阶段线程数和出发阈值

-XX:ConcGCThreads=N
-XX:CMSInitiatingOccupancyFraction=percent

G1收集器(Garbage-First)

  • 区域化堆(Region):将堆划分为多个等大小Region(每个1MB~32MB),优先回收垃圾最多的Region。
  • 回收策略
    1. 预测停顿时间:优先回收垃圾比例高的Region(Garbage-First)。
    2. Mixed GC:同时回收新生代和老年代的Region。当老年代空间达到阈值会触发
    3. Young GC:当新生代的空间不足时,G1触发Young GC回收新生代空间 Young GC主要是对Eden区进行GC,它在Eden空间耗尽时触发,基于分代回收思想和复制算法,每次Young GC都会选定所有新生代的Region,同时计算下次Young GC所需的Eden区和Survivor区的空间,动态调整新生代所占Region个数来控制Young GC开销
  • 优点可预测停顿时间(默认目标200ms)。

JDK9后成为默认GC,能预测停顿时间。

-XX:+UseG1GC

设置最大停顿时间和区域大小

-XX:MaxGCPauseMillis=time_ms
-XX:G1HeapRegionSize=size_mb
  • 阶段
    1. 初始标记(Initial Mark):标记GC Roots直接关联对象(STW)。
    2. 并发标记(Concurrent Mark):识别存活对象(并发)。
    3. 最终标记(Final Mark):处理剩余SATB(Snapshot-At-The-Beginning)记录(STW)。
    4. 筛选回收(Evacuation):选择Region进行回收(STW)。

ZGC收集器(Z Garbage Collector)

  • 目标:亚毫秒级停顿(<10ms),支持TB级堆,如云原生应用。
  • 关键技术
    • 染色指针:使用指针元数据跟踪对象状态。
    • 并发压缩:无需STW即可移动对象。
  • 适用场景低延迟、大内存应用-XX:+UseZGC)。

JDK15后成为生产特性,需要64位系统支持。

# ZGC
-XX:+UseZGC

Shenandoah收集器

Shenandoah算法通过转发指针和读屏障实现并发整理,停顿时间与堆大小无关。适用于需要低延迟且堆内存较大的场景,与ZGC类似但实现方式不同。JDK12后成为生产特性。

# Shenandoah
-XX:+UseShenandoahGC

posted @ 2025-09-21 13:13  wzzkaifa  阅读(13)  评论(0)    收藏  举报