深入理解Java虚拟机3:垃圾收集器举例

在Java虚拟机中垃圾收集算法并不是一成不变的,除了新生代和老年代分别有适合自己的算法,用户也可以根据自己的应用特点和业务需求来设置新生代和老年代所使用的垃圾收集算法,下面就来仔细介绍 HotSpot 虚拟机所使用的垃圾收集器。
HotSpot 的垃圾收集器

上图中就是 HotSpot 中在新生代(Young generation)和老年代(Tenured generation)中可用的垃圾收集器,其中的连线表示这两个收集器可以配合一起工作,而没连线的则不可以一起工作。


Serial 收集器

Serial,顾名思义,它在进行垃圾收集的时候只会使用一个CPU和一个线程,采用的是复制算法。它没有线程交互的开销,简单而高效,但缺点是在进行垃圾收集的时候需要暂停所有工作线程,结束后再恢复运行。

在企业级应用中这种停顿是难以忍受的(因为企业级应用占内存比较大,垃圾收集耗时会很长),但它在客户端模式下则是默认的新生代垃圾收集器

ParNew 收集器

ParNew 收集器实质上就是Serial 收集器的多线程版本,除了使用多线程进行垃圾收集以外,其他均与Serial 一致。它是服务器模式下默认的新生代垃圾收集器,主要原因有两个,一是性能较好,二是除了它以外,只有Serial 可以与CMS 收集器配合工作。而 CMS 收集器本身具有很大的跨时代意义,后面将会详细介绍。

不过如果是在单 CPU 环境下,ParNew 并不会比 Serial 有显著的优势,反而可能会因为线程交互的开销导致其性能比不上 Serial 收集器。

Parallel Scavenge 收集器

这也是新生代的收集器,不过它的重点不是缩短垃圾收集时的停顿时间,而是为了达到一个可控制的吞吐量。所谓吞吐量就是:运行用户代码时间/总时间,在Java虚拟机里就是:运行用户代码时间/(用户代码时间+GC时间)
它有一个叫 -XX:+UseAdaptiveSizePolicy 的参数,设置为 true 以后,再把基本的内存数据设置好(如 -Xmx 设置最大堆),然后设置 MaxGCPauseMillies(设置最大GC停顿时间)或 GCTimeRatio(设置吞吐量),然后虚拟机就可以动态调节其他参数以满足需求。

Serial Old 收集器

这是 Serial 收集器的老年代版本,同样是一个单线程收集器,使用标记-整理算法,工作过程如下图所示。
深入理解Java虚拟机3:垃圾收集器举例_第1张图片
Serial / Serial Old 收集器运行示意图

Parallel Old 收集器

它是 Parallel Scavenge 收集器的老年代版本,在注重吞吐量和 CPU 资源敏感的场合,可以优先考虑 Parallel Scavenge + Parallel Old收集器的组合,工作流程如下图所示。


深入理解Java虚拟机3:垃圾收集器举例_第2张图片
Parallel Scavenge / Parallel Old 收集器运行示意图

CMS 收集器

G1 收集器

你可能感兴趣的:(深入理解Java虚拟机3:垃圾收集器举例)