Java 垃圾回收机制之垃圾收集器

Author: Harry He


Serial 收集器

单线程收集器,收集垃圾时候必须暂停所有的工作线程,直到它收集结束。

用途:依然是虚拟机运行在客户端模式下的默认新生代收集器

特点:简单高效(与其他收集器的单线程相比),对于限定单个CPU的环境来说,它没有线程交互的开销。
在用户的桌面应用场景中分配给虚拟机管理的内存一般来说不会很大,收集几十兆甚至一两百兆的新生代,停顿的时间完全可以控制在几十毫秒到一百多毫秒以内,只要不平凡发生,还是可以接受这点停顿的。

(老年代和新生代也是和内存相关,虚拟机初始化时已经设定了使用的内存大小,并划分为三部分:新生代– 新创建的对象,
旧生代 – 经过多次垃圾回收没有被回收的对象或者大对象
持久代– JVM使用的内存,包含类信息等)

==新生代采用的是复制算法,老年代采用的是标记-整理算法==

ParNew 收集器

是Serial收集器的多线程版本,除了使用多线程进行收集之外,其余的收集算法、回收策略等都是使用一样的。

用途:许多运行在server模式下的虚拟机首选的新生代收集器

特点:除Serial收集器外,目前只有它可以与CMS(第一款真正意义上的并发收集器)收集器配合工作

局限:在单个CPU中收集效果不一定比Serial好,甚至可能会由于线程间的开销,在超线程技术实现的两个CPU的环境中都不能百分百保证比Serial好。

Parallel Scavenge 收集器

是一款新生代收集器,使用复制算法并行多线程收集器。

特点:一般的收集器的关注点是在于尽可能的缩短垃圾回收时用户线程的停顿时间,而它关注的是达到一个可以控制的吞吐量。即CPU用于运行用户代码的时间和CPU总消耗时间的比值(运行用户代码的时间/(运行用户代码的时间 + 垃圾收集的时间))

Serial old 收集器

是Serial的老年代版本

特点: 单线程,使用的是标记-整理算法

用途:同样也是使用在client模式下的虚拟机使用, 如果在server模式下,JDK1.5以及之前和Parallel Scavenge收集器搭配使用,另外一种用途就是作为CMS收集器的后备预案,在并发收集器发生并行模式失败时使用。

Parallel Old 收集器

是Parallel Scavenge收集器的老年版本, 使用的是标记-整理算法

用途:主要为了配合Parallel Scavenge新生代收集器

CMS(Concurrent Mark Sweep)收集器

是一种以获得最短回收停顿时间为目标的收集器。目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端,这类应用很重视服务的相应速度。

是基于标记-清除算法实现的。

  1. 初始标记(需 stop the world)
    标记GC Roots能直接关联到的对象
  2. 并发标记
    进行GC Roots tracing的过程
  3. 重新标记(需 stop the world)
    修正并发标记期间因用户程序继续运作而导致标记产生变动的部分对象的标记记录
  4. 并发清除

局限:对CPU资源敏感、无法处理浮动垃圾、由于基于标记-清除算法,会产生大量的空间碎片,会对大对象的分配带来麻烦。

G1 收集器

特点:并行与并发、分代收集(分多个大小相同的region)、空间整合(使用的是标记整理算法)