ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### CMS收集器(Concurrent Mark Sweep) **CMS收集器(Concurrent Mark Sweep) **是一种以获取最短回收停顿时间为目标的收集器 JDK1.5时,HotspotVM推出一款在强交互应用中可认为有划时代意义的垃圾收集器CMS(Concurrent-Mark-sweep)。CMS是HotspotVM中第一款真正意义上的并发垃圾收集器,第一次实现了让垃圾收集线程与用户线程可同时工作。 CMS关注点是尽可能缩短垃圾收集时用户线程的停顿时间,停顿时间越短就越适合与用户交互的场景。 CMS使用的是标记-清除算法,针对老年代的垃圾回收 无法与新生代垃圾回收器Parallell Scavenge组合使用,使用CMS时只能和ParNew或者时Serial配合使用。 JDK9中CMS被标记为废弃,JDK14中正式被移除 #### 特性 * 目标:获取最短回收停顿时间 * 适用于互联网B/S系统服务端 * 基于“标记-清除”算法实现 * 也称为并发低停顿收集器 * JDK1.5默认设置下CMS收集器当老年代使用了68%的空间后就会被激活 * JDK1.6CMS收集器的启动阈值提升至92% * 如果CMS运行期间预留的内存无法满足应用程序需要,就会出现一次"Concurrent Mode Failure"失败,此时将启动后备预案:临时启用Serial Old收集器重新进行老年代的垃圾收集 #### 内存碎片化 由于CMS使用的是标记-清除算法,对存活对象没有进行地址的移动,所以回收对象之后就会产生内存碎片化(可用内存不连续),对于分配一些较大内存对象内存空间的时候就很尴尬,且内存的不连续也不能使用指针碰撞技术,只能使用空闲列表来进行内存的分配 #### 优缺点 * 优点:并发收集、低延迟、低停顿 * 缺点: 1.对CPU资源非常敏感:在并发阶段虽然不会造成STW的发生,但是会因为其垃圾回收线程占用的服务器资源导致程序变慢,总的吞吐量将会有一定的降低 2.无法处理浮动垃圾(Floating Garbage):在并发标记的阶段中,如果产生新的垃圾对象,CMS将无法对这些垃圾进行识别标记(从GC Roots直接关联对象出发遍历整个对象引用结构),就会导致这一部分的垃圾没有被及时的回收掉。只能在下一次执行GC的时候对这一部分垃圾进行处理 3.“标记-清除”算法会产生大量空间碎片,大对象无法存放发生后,不得不提前的触发Full GC #### CMS"标记-清除"算法实现 1. 初始标记(CMS initial mark) 2. 并发标记(CMS concurrent mark) 3. 重新标记(CMS remark) 4. 并发清除(CMS concurrent sweep) **说明:**初始标记、重新标记仍然需要Stop The World #### 相关参数 * \-XX:+UseConcMarkSweepGC:手动指定使用CMS,开启CMS之后,会自动将ParNew打开,即-XX:+UseParNewGC,此时JVM垃圾回收将会是**ParNew(新生代)+CMS(老年代)+Serial Old(CMS的后备)**的组合。 * \-XX:+CMSInitiatingOccupanyFraction:设置堆内存使用率阈值,一旦达到该设置的阈值,CMS将会开启进行垃圾回收。 * JDK5默认值为68。即68%,JDK6以上默认值为92 * **如果内存增长的较慢,可以增大该阈值,降低CMS的触发频率,如果内存增长较快,要适当的减小该阈值,以免触发Serial Old串行垃圾回收器,减少Full GC的次数**。 * \-XX:+UseCMSCompactAtFullCollection:用于CMS在垃圾回收之后对内存碎片进行整理,这个过长将会存在STW。 * \-XX:+CMSFullGCsBeforeCompaction:设置在执行多少次FullGC后对内存空间进行压缩整理,和-XX:+UseCMSCompactAtFullCollection搭配使用。 * \-XX:ParallelCMSThreads:设置CMS的线程数量,CMS默认线程数量为(**ParallelGCThreads**\+ 3)/ 4。**ParallelGCThreads是年轻代并行收集器Parallel的线程数**