上图中就是 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 收集器的老年代版本,同样是一个单线程收集器,使用标记-整理算法,工作过程如下图所示。Parallel Old 收集器
它是 Parallel Scavenge 收集器的老年代版本,在注重吞吐量和 CPU 资源敏感的场合,可以优先考虑 Parallel Scavenge + Parallel Old收集器的组合,工作流程如下图所示。
CMS 收集器
G1 收集器
略