JDK诞生 Serial追随 提高效率,诞生了Parallel Scavenge,为了配合CMS,诞生了ParNew,CMS是1.4版本后期引入,CMS是里程碑式的GC,它开启了并发回收的过程,但是CMS毛病较多,因此目前没有任何一个JDK版本默认是CMS。
并发垃圾回收是因为无法忍受STW
1. Serial & Serial Old
Serial & Serial Old分别是新生代和老年代的垃圾回收器,串行回收,现在一般不用了。
Serial
a stop-the-world(STW),copying collector which uses a single GC thread.
单CPU效率最高 虚拟机是Client模式的默认垃圾回收器。
单线程的,当进行垃圾回收时会禁止其它一切操作(STW),它不是立刻停止,会找到一个safe point,一个安全点禁止。
由于Serial收集器进行垃圾回收时的等待时间,即STW时间较长,所以只适合在内存空间较小的情况下使用
Serial Old
a stop-the-world(STW),mark-sweep-compact collector that uses a single GC thread.
用于老年代的垃圾收集器,采用标记清除或整理算法
2. Parallel Scavenge & Parallel Old
现在常用的是这两种收集器的组合,简称PS+PO,默认的也是这两种。多线程进行回收
Parallel Scavenge
年轻代 并行回收
a stop-the-world(STW),copying collector which uses multiple GC threads.
Parallel Old
a compacting collector that uses miltiple GC threads.
使用整理算法
3. ParNew & CMS
ParNew
年轻代 配合CMS的并行回收,是Parallel Scavenge的变种
- a stop-the-world,copying collector which uses multiple GC threads.
- It differs from "Parallel Scavenge" in that it has enhancements that make it usable with CMS.
- For example,"ParNew" does the synchronization needed so that it can run during the concurrent phases of CMS.
默认线程数为CPU核数
3.1 CMS
ConcurrentMarkSweep 老年代 并发的, 垃圾回收和应用程序同时运行,降低STW的时间(200ms) CMS问题比较多,所以现在没有一个版本默认是CMS,只能手工指定 CMS既然是MarkSweep,就一定会有碎片化的问题,碎片到达一定程度,CMS的老年代分配对象分配不下的时候,使用SerialOld 进行老年代回收 想象一下:
PS + PO --> 加内存 换垃圾回收器 --> PN + CMS + SerialOld(几个小时 - 几天的STW) 几十个G的内存,
单线程回收 --> G1 + FGC 几十个G --> 上T内存的服务器 ZGC
- concurrent mark sweep
- a mostly concurrent,low-pause collector.
- phases
1 initial mark
2 concurrent mark
3 remark
4 concurrent sweep
垃圾回收线程和工作线程同时进行
CMS的四个阶段如下:
CMS的四个阶段.png
初始标记对GC roots进行标记,程序运行时对新产生的垃圾并发标记,重新标记:对并发标记时漏掉的或新增的垃圾进行标记(产生STW),最后并发清理,清理时产生的新垃圾为浮动垃圾,交给下一轮处理。
3.1.1 CMS缺点
CMS的问题
- Memory Fragmentation 内存碎片化
-XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction 默认为0 指的是经过多少次FGC才进行压缩
当碎片化内存装不下其他对象时,会使用Serial Old进行标记整理
- Floating Garbage 浮动垃圾
Concurrent Mode Failure
产生:if the concurrent collector is unable to finish reclaiming the unreachable objects before the tenured generation fills up, or if an allocation cannot be satisfiedwith the available free space blocks in the tenured generation, then theapplication is paused and the collection is completed with all the applicationthreads stopped解决方案:降低触发CMS的阈值
PromotionFailed
解决方案类似,保持老年代有足够的空间
–XX:CMSInitiatingOccupancyFraction 92% 可以降低这个值,让CMS保持老年代足够的空间
网友评论