【JVM】CMS垃圾回收器
一、简介
Concurrent Mark Sweep,是一种以获取最短回收停顿时间为目标的收集器,尤其重视服务的响应速度。
CMS是老年代垃圾回收器,基于标记-清除算法实现。新生代默认使用ParNew收集器,基于复制算法
二、垃圾回收过程
分为四个步骤进行垃圾回收:初始标记,并发标记,重新标记,并发清除。只有初始标记和重新标记需要停顿。
- 初始标记。只是标记一下GC Roots能直接关联到的老年代对象,速度很快。这一阶段会STW
- 并发标记。就是进行GC Roots的Tracing,处理器可以与用户线程一起工作。
- 重新标记。为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段也会触发STW,停顿时间会比初始标记阶段稍长,远比并发时间短。
- 并发清除,处理器可以与用户线程一起工作。
可达性分析方法
- 通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为“引用链”,当一个对象到GC Roots没有任何引用链相连时,说明这个对象是可回收的。
- Java语言中,可作为GC Roots的对象包括以下几种:虚拟机栈中引用的对象,方法区中类静态属性引用的对象,方法区中常量引用的对象,本地方法栈中引用的对象。
三、垃圾回收触发时机
新生代垃圾回收触发时机:当 eden 区内存无法为一个新对象分配内存时,就会触发 Minor GC
老年代垃圾回收触发时机:
2、老年代使用率达到阈值
CMSInitiatingOccupancyFraction,默认92%。3、永久代的使用率达到阈值
CMSInitiatingPermOccupancyFraction,默认92%,前提是开启 CMSClassUnloadingEnabled。4、新生代的晋升担保失败。老年代没有足够的空间来容纳全部的新生代对象或历史平均晋升到老年代的对象,如果不够的话,就提早进行一次老年代的回收,防止下次进行YGC的时候发生晋升失败。
四、垃圾回收如何做到STW
JVM有个叫做“安全点”和“安全区域”的东西,在发生GC时,所有的线程都会执行到“安全点”停下来。
在需要GC的时候,JVM会设置一个标志,当线程执行到安全点的时候会轮询检测这个标志,如果发现需要GC,则线程会自己挂起,直到GC结束才恢复运行。
但是对于一些没有获得或无法获得CPU时间的线程,就没办法等到它执行到安全点了,所以这个时候只要这个线程是在安全区域的,也可以进行GC,安全区域是一段代码段,在这段代码段中对象的引用关系不会发生变化,所以这个时候进行GC也是安全的。
五、关于FullGC
- Full GC == Major GC指的是对老年代/永久代的stop the world的GC
- Full GC的次数 = 老年代GC时 stop the world的次数
- Full GC的时间 = 老年代GC时 stop the world的总时间
- CMS 不等于Full GC,我们可以看到CMS分为多个阶段,只有stop the world的阶段被计算到了Full GC的次数和时间,而和业务线程并发的GC的次数和时间则不被认为是Full GC。CMS主要可以分为initial mark(stop the world), concurrent mark, remark(stop the world), concurrent sweep几个阶段,其中initial mark和remark会stop the world。
六、CMS缺点
- 垃圾回收时会占用一部分线程,导致系统变慢,总吞吐量会降低。
- 无法处理浮动垃圾,需要预留足够的内存空间给用户线程使用,可以通过 -XX:CMSInitiatingOccupancyFraction 参数控制触发垃圾回收的阈值。
- 如果预留的内存无法满足程序需要,就会出现“Concurrent Mode Failure”失败,这时将启动应急预案,启用Serial Old 进行垃圾回收,停顿时间会变长。所以-XX:CMSInitiatingOccupancyFraction 参数的值设置的太高,会导致频繁“Concurrent Mode Failure”失败,性能反而降低。
- 标记-清理,容易产生内存碎片。-XX:+UseCMSCompactAtFullColletion 开启碎片整理功能,默认开启,-XX:CMSFullGCsBeforeCompaction,控制多少次不压缩的FullGC之后来一次带压缩的
七、常见问题
1、promotion failed – concurrent mode failure
Minor GC后, Survivor空间容纳不了剩余对象,将要放入老年代,老年代有碎片或者不能容纳这些对象,就产生了concurrent mode failure, 然后进行stop-the-world的Serial Old收集器。
解决办法:-XX:UseCMSCompactAtFullCollection -XX:CMSFullGCBeforeCompaction=5 或者调大新生代或者Survivor空间
2、concurrent mode failure
CMS是和业务线程并发运行的,在执行CMS的过程中有业务对象需要在老年代直接分配,例如大对象,但是老年代没有足够的空间来分配,所以导致concurrent mode failure, 然后需要进行stop-the-world的Serial Old收集器。
解决办法:+XX:CMSInitiatingOccupancyFraction,调大老年带的空间,+XX:CMSMaxAbortablePrecleanTime
3、碎片整理
-XX:+UseCMSCompactAtFullCollection 强制进行空间碎片整理
CMS 采用标记算法,会产生大量的空间碎片。以上参数就是强制执行一次空间碎片整理,但是空间碎片整理会引发STW。
-XX:+CMSFullGCsBeforeCompaction 配置经过几次的FullGC进行空间碎片整理
-XX:+CMSFullGCsBeforeCompaction=10 经过10次FGC后进行空间碎片整理,以降低STW次数
【JVM】CMS垃圾回收器的更多相关文章
- jvm——CMS 垃圾回收器(未完)
https://matt33.com/2018/07/28/jvm-cms/ 阶段1:Initial Mark stop-the-wolrd 标记那些直接被 GC root 引用或者被年轻代存活对象所 ...
- JVM七大垃圾回收器上篇Serial、ParNeW、Parallel Scavenge、 Serial Old、 Parallel Old、 CMS、 G1
GC逻辑分类 垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商.不同版本的JVM来实现. 由于JDK的版本处于高速迭代过程中,因此Java发展至今已经衍生了众多的GC版本. 从不同角度分析垃圾收 ...
- 【JVM】垃圾回收器总结(2)——七种垃圾回收器类型
七种垃圾回收器类型 GC的约定参数 DefNew——Default New Generation Tenured——Serial Old ParNew——Parallel New Generation ...
- JVM七大垃圾回收器下篇G1(Garbage First)
G1回收器:区域化分代式 既然我们已经有了前面几个强大的GC,为什么还要发布Garbage First (G1)GC? 原因就在于应用程序所应对的业务越来越庞大.复杂,用户越来越多,没有GC就不能保 ...
- 探索ParNew和CMS垃圾回收器
前言 上篇文章我们一起分析了JVM的垃圾回收机制,了解了新生代的内存模型,老年代的空间分配担保原则,并简单的介绍了几种垃圾回收器.详细内容小伙伴们可以去看一下我的上篇文章:秒懂JVM的垃圾回收机制. ...
- 关于 CMS 垃圾回收器,你真的懂了吗?
大家好,我是树哥. 前段时间有个小伙伴去面试,被问到了 CMS 垃圾回收器的详细内容,没答出来.实际上,CMS 垃圾回收器是回收器历史上很重要的一个节点,其开启了 GC 回收器关注 GC 停顿时间的历 ...
- 深入理解JVM一垃圾回收器
上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某一种算法进行垃圾回收,而是将不同的垃圾回收算法包装在不同的垃圾回收器当中,用户可以根据自身的需求,使用不同的垃 ...
- jvm学习-垃圾回收器(四)
说明 各种垃圾回收算法都有各自的优缺点.jvm也并没有只采用一种垃圾算法.并提供几种组合供我根据场景进行选择. jvm内存结构 Person p=new Person(); 1.程序里面创建一个对象会 ...
- 深入探究JVM之垃圾回收器
@ 目录 前言 正文 一.垃圾收集算法 标记-复制 标记-清除 标记-整理 分代回收 二.常用的垃圾回收器 Serial/SerialOld ParNew Parallel Scavenge/Para ...
随机推荐
- flask实战-个人博客-模板 --
模板 personalBlog采用典型的博客布局,左侧三分之二为主体,显示文章列表.正文:右侧三分之一为边栏,显示分为类列表.社交链接等.现在的工作是将HTML文件加工为模板,并创建对应的表单类,在模 ...
- CanvasRenderingContext2D.fillText(text, x, y [, maxWidth]);
CanvasRenderingContext2D.fillText(text, x, y [, maxWidth]); [, maxWidth]的意思是,方括号代表可有可无,有fillText(tex ...
- 洛谷 P1801 黑匣子_NOI导刊2010提高(06) 题解
昨晚恶补了一下二叉堆的内容 然后就找了几个二叉堆的题来做awa 然后发现用二叉堆做这题复杂度是O(nlogn) 但是有O(n)的解法 (某大佬这么说) 思路大概就是: 利用一个大根堆一个小根堆来维护第 ...
- OpenStack总体架构概览&OpenStack核心组件介绍
下面个是51CTO上一位朋友发布的O版OpenStack核心组件说明,总结的非常到位,所以我就不再造轮子了.~,~ https://down.51cto.com/data/2448945 私有云 公有 ...
- 每日一问:简述 View 的绘制流程
Android 开发中经常需要用一些自定义 View 去满足产品和设计的脑洞,所以 View 的绘制流程至关重要.网上目前有非常多这方面的资料,但最好的方式还是直接跟着源码进行解读,每日一问系列一直追 ...
- Oracle_其他人连接不上自己电脑
1. 修改文件G:\app\eric\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora文件,listener中的address中加一个你的ip开头的 ...
- python3.5以上版本,typing模块提高代码健壮性
一 前言 Python是一门弱类型的语言,很多时候我们可能不清楚函数参数类型或者返回值类型,很有可能导致一些类型没有指定方法,在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数, ...
- 关于“100g文件全是数组,取最大的100个数”解决方法汇总
原题如下: 有一个100G大小的文件里存的全是数字,并且每个数字见用逗号隔开.现在在这一大堆数字中找出100个最大的数出来. 我认为,首先要摸清考官的意图.是想问你os方面的知识,还是算法,或者数据结 ...
- sort排序与二分查找
#include<iostream> #include<vector> #include<algorithm> #include<string> usi ...
- Hadoop vs Elasticsearch – Which one is More Useful
Hadoop vs Elasticsearch – Which one is More Useful Difference Between Hadoop and Elasticsearch H ...