《深入理解java虚拟机》3.5之垃圾收集器

 2019-12-22 10:57  阅读(736)
文章分类:JVM

3.5.1、串行收集器(Serial)

上古时期的可爱的单线程垃圾收集器,使用一个线程或者一个cpu(核心)去回收垃圾,在收集垃圾时必须使整个虚拟机都停下来(stop the world)

2019120001423\_1.png

优点:简单高效(对于限定cpu的机器来说),对于client模式虚拟机的新生代来说是一个不错的选择

缺点:随着机器性能的提升,效率提升不明显

3.5.2、ParNew收集器

parNew是serial收集器的多线程版本,除了在收集阶段使用多线程外其他的特性几乎一样

ParNew 收集线程数与 CPU 的数量相同, 因此在 CPU 数量过大的环境中, 可用-XX:ParallelGCThreads=参数控制 GC 线程数

2019120001423\_2.png

相比于serial收集器,ParNew更多的用在server模式虚拟机的新生代

3.5.3 Parallel Scavenge 收集器

Parallel Scavenge收集器更注重系统的吞吐量(Througthput)
吞吐量=运行用户代码的时间/(运行用户代码的时间+垃圾收集的时间)
停顿的时间越短就越适合用作用户交互式的软件
而吞吐量越大则意味着适合做后台程序/服务 后台运行的任务
可以使用如下参数
-XX:MaxGCPauseMillis 垃圾回收停顿的时间
-XX:GCTimeRatio 设置系统吞吐量
-XX:MaxGCPauseMillis被设置小不代表垃圾回收就变快而是以吞吐量和新生代空间为代价的
例如原来10秒收集一次,每次停顿100ms
调小之后5秒收集一次,一次停顿70ms
原来10s停顿100ms,现在10秒停顿140ms

每次垃圾回收的时间是短了,但是这也意味着吞吐量下来了

3.5.4 Serial Old 收集器
serial收集器的老年代版本

3.5.5 Paralle Old 收集器

Parallel Scavenge收集器的老年代版本

3.5.6 CMS(concurrent Mark sweep) 收集器

并发标记清除收集器,采用标记清除算法,主要分为以下4个步骤

初始标记(CMS initial mark)

stop the world 标记CG ROOTS 能直接关联到的对象,该过程速度快
并发标记(CMS concurrent mark)
主要负责CG ROOTS的跟踪
重新标记(CMS remark)
修改程序在并发标记阶段因为用户程序继续运行而产生变动的一部分对象的标记
并发清除(CMS concurrent sweep)

多线程清除要回收的对象

2019120001423\_3.png

优点:速度快、低停顿
缺点:
1、对CPU资源敏感
在并发标记阶段虽然不会导致stop the world 但是会占用一部分cpu,导致该阶段程序变慢,默认的线程数为(x+3)/4,x代表cpu的核心数,当x>=4时,并发标记阶段占用>=25%的cpu资源,当x<4时对程序影响比较大,如果为2核心cpu,那么就意味着要分出一个核心给垃圾收集器。

2、CMS 无法清除浮动垃圾
因为在并发清除阶段,整个程序还在运行,也会产生一部分垃圾,这部分垃圾出现在标记过程之后,CMS无法回收,只能等到下一次垃圾回收,也正是如此,需要在进行并发清除阶段预留足够的空间给用户线程,
否则会出现ConCurrent Mode Failure,然后出发一次Full GC

3、会产生碎片
当碎片问题太严重时,就需要提前出发一次Full GC,CMS提供了参数 –XX:+UserCMSCompactAtFullCollection 用于在CMS顶不住要进行Full GC之前开启内存碎片整理,当然停顿时间也会变长

点赞(1)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 《深入理解java虚拟机》3.5之垃圾收集器

相关推荐