jvm垃圾回收算法以及常见的垃圾回收器

目录

常见的垃圾回收算法

标记复制算法

标记清除算法

标记整理算法

垃圾回收器

1. Serial收集器

2. Parallel Scavenge/ Parallel Old收集器

3. ParNew + CMS

CMS

为什么CMS停顿时间短?

G1 (Garbage First)

ZGC (The Z Garbage Collector)

如何选择JVM垃圾回收器

有多个维度需要注意:

常见的垃圾回收算法

标记复制算法

将内存分为相等的两块,每次仅使用其中的一块;垃圾回收时,标记存活的对象,将存活的对象复制到另一块区域中,并清理当前区域。(根据两块的逻辑可以判断出这是针对年轻代的一种算法

问题:

标记清除算法

算法分为“标记”和“清除”阶段:标记存活的对象, 统一回收所有未被标记的对象(一般选择这种);也可以反过来,标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象 。它是最基础的收集算法,比较简单,但是会带来
两个明显的问题:
1. 效率问题 (如果需要标记的对象太多,效率不高)
2. 空间问题(标记清除后会产生大量不连续的碎片)

标记整理算法

根据老年代的特点特出的一种标记算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存,优化了“标记-清除”算法的问题。

垃圾回收器

没有完美的垃圾回收器,只能很具具体场景选择具体的垃圾回收器。

1. Serial收集器

  • 特点:单线程,Stop-The-World,直到它结束
  • 算法:复制算法(年轻代) + 标记-整理(老年代)
  • 适用场景:
    • 客户端应用
    • 小内存(几十MB到一两百MB)
    • 单核CPU环境
  • 优点:简单高效,没有线程交互开销
  • 缺点:停顿时间长
  • 参数:-XX:+UseSerialGC

-XX:+UseSerialGC -XX:+UseSerialOldGC

2. Parallel Scavenge/ Parallel Old收集器

  • 特点:多线程并行,关注吞吐量
  • 算法:复制算法 + 标记-整理
  • 适用场景:
    • 后台计算密集型应用
    • 科学计算、批处理任务
    • 不关注单次停顿时间,关注整体吞吐
  • 优点:吞吐量高,CPU利用率高
  • 缺点:停顿时间不可控,对延迟不敏感
  • 参数:
    • -XX:+UseParallelGC
    • -XX:+UseParallelOldGC
    • -XX:ParallelGCThreads=4
    • -XX:MaxGCPauseMillis=100

其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略,甚至STW等等)和Serial收集器类似。默认的收集线程数跟cpu核数相同,当然也可以用参数(-XX:ParallelGCThreads)指定收集线程数,但是一般不推荐修改。所谓吞吐量就是CPU中用于运行用户代码的时间与CPU总消耗时间的比值。

在注重吞吐量以及CPU资源的场合,都可以优先考虑 Parallel Scavenge收集器和Parallel Old收集器(JDK8默认的新生代和老年代收集器)。

3. ParNew + CMS

ParNew ,主要针对年轻代,ParNew收集器其实跟Parallel收集器很类似,区别主要在于它可以和CMS收集器配合使用

  • 特点:Serial的多线程版本
  • 算法:复制算法
  • 作用:与CMS配合使用
CMS

Concurrent Mark Sweep,主要针对老年代

  • 特点:并发收集,减少停顿时间;在 JDK 14 及之后的版本中,你无法再使用 CMS 垃圾回收器
  • 算法:标记-清除
  • 适用场景:
    • Web服务器、GUI应用
    • 对响应时间敏感的系统
  • 优点:低停顿,用户体验好
  • 缺点:
    • 产生内存碎片
    • CPU资源敏感(会和服务抢资源)
    • 并发失败时退化为Serial Old
    • 执行过程中的不确定性,会存在上一次垃圾回收还没执行完,然后垃圾回收又被触发的情况,特别是在并发标记和并发清理阶段会出现,一边回收,系统一边运行,也许没回收完就再次触发full gc,也就是"concurrentmode failure",此时会进入stop the world,用serial old垃圾收集器来回收
  • 参数:-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
为什么CMS停顿时间短?

CMS GC: 初始标记(短暂STW) → 并发标记 → 重新标记(短暂STW) → 并发清除

  1. 将GC工作分摊到多个阶段,只有初始标记和重新标记需要短暂STW

  2. 并发标记和并发清除阶段与用户线程一起运行,不停止应用

  3. 使用卡表和增量更新等技术,减少重新标记阶段的工作量

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用,它是HotSpot虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作(Parallel收集器工作期间必须STW)

G1 (Garbage First)

  • 特点:面向服务端,可预测的停顿时间模型
  • 算法:标记-整理 + 分区算法
  • 内存布局:将堆划分为多个Region(1MB~32MB)
  • 适用场景:
    • 大内存应用(6GB+
    • 要求停顿时间可控
    • JDK9+ 的默认选择
  • 优点:
    • 停顿时间可控
    • 整体吞吐量与Parallel相当
    • 有效处理大内存
  • 缺点:
    • 内存占用稍高,堆内存 < 4GB时,G1优势不明显
    • JDK6/7中不够成熟
    • 追求极致吞吐时,Parallel更优
    • 需要亚毫秒级停顿时,ZGC更合适
  • 参数:
    • -XX:+UseG1GC
    • -XX:MaxGCPauseMillis=150
    • -XX:G1HeapRegionSize=16m
  • Q: 为什么G1能替代CMS?

  • A: "G1解决了CMS的内存碎片问题,同时提供了可预测的停顿时间,在大内存场景下表现更好"

ZGC (The Z Garbage Collector)

  • 特点:超低停顿(<10ms),不分代
  • 算法:并发标记-整理
  • 适用场景:
    • 超大堆内存(TB级别
    • 极致低延迟要求
    • 新架构应用
  • 优点:
    • 停顿时间极短且与堆大小无关
    • 吞吐量损失小
  • 缺点:JDK15才正式生产可用,兼容性要求高
  • 参数:
    • -XX:+UseZGC
    • -Xmx16g -Xms16g
    • -XX:SoftMaxHeapSize=14g
    • -XX:MaxGCPauseMillis=10

如何选择JVM垃圾回收器

有多个维度需要注意:

  • 应用类型:Web服务、批处理、客户端?
  • 堆内存大小:小(<2G)、中(2-8G)、大(>8G)?
  • 停顿要求:可容忍秒级、百毫秒级、十毫秒级?
  • 吞吐要求:最大化吞吐量还是保证响应时间?
  • JDK版本:JDK8还是JDK11+?

小内存或客户端 → Serial
批处理重吞吐 → Parallel Scavenge + Parallel Old  
JDK8 Web应用低延迟 → ParNew + CMS
JDK9+ 现代应用 → G1 (默认)
超大堆极致低延迟 → ZGC/Shenandoah

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值