Java 常见的垃圾收集器及算法

一、常见垃圾收集器对比

实际上,垃圾收集器(GC,Garbage Collector)是和具体 JVM 实现紧密相关的,不同厂商(IBM、Oracle),不同版本的jvm,提供选择也不一样,目前主要还是Oracle JDK 。

收集器 定义 使用的场景 备注
Serial GC GC,它是最古老的垃圾收集器,“Serial”提现在其收集工作线程的,并且在进行垃圾收集过程中,会进入臭名昭著的“Stop-The-World” 状态。当然,其单线程设计意味着精简的GC实现,无需维护复杂的数据结构,初始化也简单,所以client模式下的JVM的默认选项。 从年代的角度,通常将其老年代实现单独称作Serial Old,采用了标记-整理(Mark-Compact)算法, 区别于新生代的复制算法。 Serial收集器:串行运行;作用于新生代;复制算法;响应速度优先;适用于单CPU环境下的client模式。Serial Old收集器:串行运行;作用于老年代;标记-整理算法;响应速度优先;单CPU环境下的Client模式。
ParNew GC 很明显是个新生代 GC 实现,它实际是Serial GC的多线程版本,常见的应用场景是配合老年代的CMS GC工作。 并行运行;作用于新生代;复制算法;响应速度优先;多CPU环境Server模式下与CMS配合使用。
CMS GC CMS(Concurrent Mark Sweep) GC,基于标记-清除(Mark-Sweep)算法,设计的目标是尽量减少停顿时间,这一点对于Web等反应时间敏感的应用非常重要,一直到今天,仍然有很多系统使用CMS GC 。 但是,CMS采用的标记-清除算法,存在碎片化问题,所以可能会导致长时间运行情况下发生full GC ,导致恶劣停顿。 并发运行;作用于老年代;标记-清除算法;响应速度优先;适用于互联网或B/S业务。
Parrallel GC 在早期JDK 8 版本中, 它是server模式JVM的默认GC选择,也被称作是吞吐量优先的GC。它的算法和Serian GC比较相似,尽管实现要复杂的多,其特点是新生代和老年代GC到时并行进行的。吞吐量优先;适用于后台运算而不需要太多交互的场景。 Parallel Scavenge收集器:并行运行;作用于新生代;复制算法;Parallel Old收集器:并行运行;作用于老年代;标记-整理算法;
G1 GC 这是一种兼顾吞吐量和停顿时间的 GC 实现,是 Oracle JDK 9 以后的默认 GC 选项。G1 可以直观的设定停顿时间的目标,相比于 CMS GC,G1 未必能做到 CMS 在最好情况下的延时停顿,但是最差情况要好很多。G1 GC 仍然存在着年代的概念,但是其内存结构并不是简单的条带式划分而是类似棋盘的一个个 region。Region 之间是复制算法,但整体上实际可看作是标记 - 整理(Mark-Compact)算法,可有效避免内存碎片化,由其是当Java 堆非常大的时候,G1的优势更明显。G1 吞吐量和停顿表现都非常不错。CMS 已经在 JDK 9 中被标记为废弃(deprecated)。 并发运行;可作用于新生代或老年代;标记-整理算法+复制算法;响应速度优先;面向服务端应用。

二、常见垃圾算法

算法 定义 优点 缺点
复制(Copying)算法 将活着的对象复制到to区域 拷贝过程对象顺序放置,就可以避免内存碎片化 既然要进行复制,既要提前预留内存空间,有一定浪费;另外对于G1这种拆分为大量region的GC,复制不是移动,意味着GC需要维护region之间对象引用光纤,这开销不小,会有内存占用或时间开销。
标记 - 清除(Mark-Sweep)算法 首先进行标记工作,标识出所有要回收的对象,然后进行清除。 算法简单,需要的内存空间相比“复制算法”要小。 除了做 标记、清除过程效率有限,另外就是不可避免的出现碎片化问题,这就导致其不适合特别大的堆;否则,一旦出现Full GC ,暂停时间可能无法接受。
标记 - 整理(Mark-Compact) 类似于标记-清除,但为避免内存碎片化,它会在清理过程中将对象移动,以确保移动后的对象用连续的内存空间。 避免内存碎片化,它会在清理过程中将对象移动,以确保移动后的对象用连续的内存空间。

你可能感兴趣的:(jvm)