JVM -- CMS
并发的标记—清除(Concurrent Mark Sweep,缩写为 CMS)收集器,使得在整个收集的过程中只是很短的暂停应用的执行,可通过在 JVM 参数中设置-XX:UseConcMarkSweepGC 来使用此收集器,不过此收集器仅用于old和Perm(永生)的对象收集,并发的标记—清除较之Stop-The-World 的标记—清除复杂了很多,来看看:
并发标记—清除做到的是在标记访问每一个节点时以及清除不活跃的对象时采用和应用并发的方式,仅需在初始化标记节点状态以及最终标记节点状态时需要暂停整个应用,因此其造成的应用的暂停的时间会比较的短。
并发标记—清除为了保证尽量短的造成应用的暂停,首先从分配内存上做了改动,CMS提供了两个 free lists,一个用于存放小对象,另外一个则用于存放大对象,当 JVM 需要给对象分配内存时,则通过 free list 来找到可用的堆地址,并进行内存的分配以及将此地址从 free
list 删除,当 CMS 回收对象内存后,则将其相应的地址重新放入此 free list 中,这样的好处是在回收对象的时候不需要做对象的移动等,因此可以让回收过程并发的进行。
接着来看看并发标记—清除的执行步骤:
1.Initial Marking --初始标记
此步需要暂停整个应用,JVM 扫描整个 old generation 中根对象可直接访问到的对象,并对这些对象进行标记,对于标记的对象 CMS 采用一个外部的 bit 数组来进行记录。
2. Concurrent Marking --并发标记
在初始化标记完毕后,CMS 恢复所有应用的线程,同时开始并发的对之前标记过的对象进行轮循,以标记这些对象可访问的对象。CMS 为了确保能够扫描到所有的对象,避免在 Initial Marking 中还有未标识到的对象,采用的方法为找到标记了的对象,并将这些对象放入 Stack 中,扫描时寻找此对象依赖的对象,如果依赖的对象的地址在其之前,则将此对象进行标记,并同时放入 Stack 中,如依赖的对象地址在其之后,则仅标记该对象。
在进行 Concurrent Marking 时 minor GC 也可能会同时进行,这个时候很容易造成旧生代对象引用关系改变,CMS 为了应对这样的并发现象,提供了一个 Mod Union Table 来进行记录,在这个 Mod Union Table 中记录每次 minor GC 后修改了的 Card 的信息。
在进行 Concurrent Marking 时还有可能会出现的一个并发现象是应用修改了旧生代中的对象的引用关系,CMS 中仍然采用 Card Table 的方式来进行记录,在 Card 中将某对象标识为 dirty 状态,但即使是这样仍然可能会出现一种现象导致不再被引用的对象仍然是 marked的状态:
3.Final Marking -- 最终标记
此步需要暂停整个应用,由于在 Concurrent Marking 时应用可能会修改对象的引用关系或创建新的对象,因此需要把这些改变或新创建的对象也进行扫描,CMS 递归扫描 Mod Union Table 以及 Card Table 中 dirty 的对象,并进行标记。
4.Concurrent Sweeping -- 并发清除
在完成了 Final Marking 后,恢复所有应用的线程,就进入到这步了,这步需要负责的是将没有标记的对象进行回收。
回收过程是并发进行的,而 JVM 分配对象内存(尽管 CMS 仅用于 old generation,但有些时候会由于应用创建的对象过大导致直接分配到 old generation 的现象,另外一种现象就是 young generation 经过回收后需要转入 old generation 的对象)和 CMS 释放内存又都是操
作 free list,会产生 free list 竞争的现象,因此 CMS 在此增加了 Mutual exclusion locks,以 JVM分配优先。
CMS 为了避免每次回收后回收到的大小都比之前分配出去的内存小,在进行 sweeping的时候,还会尽量的将相邻的块重新组装为一个块,sweeping 为了避免和 JVM 分配对象内存产生冲突,采用的方法为首先从 free list 中删除块,组装完毕后再重新放入块中,为了能够从 free list 中删除指定的块,CMS 将 free list 设计为了双向链表。
总结:
CMS 中的耗时的过程都是和应用并发进行的,这也是 CMS 最突出的优点,使得其造成的应用的暂停时间比 Mark-Sweeping 的方式短了很多,但同时也意味着 CMS 会和应用线程争抢 CPU 资源, CMS 回收内存的方式也使得其很容易产生内存碎片,降低了空间的利用率,
另外就是 CMS 在回收时容易产生一些应该回收但需要等到下次 CMS 才能被回收掉的对象,例如上图中的 C 对象,称为“浮动垃圾“,这也就要求了采用 CMS 的情况下需要提供更多的可用的旧生代空间,总体来说 CMS 很适用于对响应时间要求很高、CPU 资源竞争不是很激烈以及内存空间相对更充足的系统。
MS 为了降低和应用争抢 CPU 资源的现象发生,还提供了一种增量的模式,称为 i-CMS,在这种模式下,CMS 仅启动一个处理器线程来并发的扫描标记和清除,并且该线程在执行一小段时间后就会先将 CPU 使用权让出来,分多次多段的方式来完成整个扫描标记和清除
的过程,这样降低了对于 CPU 资源的消耗,但同时也降低了 CMS 的性能,因此仅适用于 CPU少的应用。
CMS 为了减少产生的内存碎片,提高 jvm 空间的利用率,提供了一个整理碎片的功能,可通过在 jvm 中指定-XX:+ UseCMSCompactAtFullCollection (开启对内存空间的整理工作)来启动此功能,在启动了此功能后默认为每次 Full GC 的时候都会进行整理,也可以通过-XX:CMSFullGCsBeforeCompaction=来指定多少次 Full GC 后才执行整理,不过要注意的是,整理这个步骤是需要暂停整个应用的。
[--> 注 <--]
Mod Union Table ----在并发标记阶段Minor GC 造成的对象之间引用的变化
Card Table --- 在并发标记阶段应用程序本身造成对象之间引用的变化。
JVM -- CMS的更多相关文章
- JVM CMS 常用参数配置(修订)
搜集到的一些参数内容,比较有用,大部分转载自并发编程网ifeve.com. -XX:+UseConcMarkSweepGC该标志首先是激活CMS收集器.默认HotSpot JVM使用的是并行收集器. ...
- jvm——CMS 垃圾回收器(未完)
https://matt33.com/2018/07/28/jvm-cms/ 阶段1:Initial Mark stop-the-wolrd 标记那些直接被 GC root 引用或者被年轻代存活对象所 ...
- JVM日志和参数的理解
写这篇wiki的目的:最近在调整Hbase的JVM,翻了些文档和wiki,想写点东西,给自己和想了解jvm日志和参数的同 学提供些帮助. 一:理解GC日志格式,读GC日志的方法 1:开启日志 -ver ...
- 【GoLang】golang垃圾回收 & 性能调优
golang垃圾回收 & 性能调优 参考资料: 如何监控 golang 程序的垃圾回收_Go语言_第七城市 golang的垃圾回收(GC)机制 - 两只羊的博客 - 博客频道 - CSDN.N ...
- Java内存溢出优化性能优化
高性能应用构成了现代网络的支柱.LinkedIn有许多内部高吞吐量服务来满足每秒数千次的用户请求.要优化用户体验,低延迟地响应这些请求非常重要. 比如说,用户经常用到的一个功能是了解动态信息——不断更 ...
- 【JAVA】JAVA相关知识点收集
下面这些链接都是我这段时间(7月-9月)看过的.感觉自己现在处于一个疯狂吸收知识的阶段,如果是文字的方式一点一点搬运到自己的博客既重复又费时间,只有等自己积累到一定程度后才能进行原创性高质量的产出吧. ...
- JVM GC算法 CMS 详解(转)
前言 CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性 ...
- JVM实用参数(七)CMS收集器
HotSpot JVM的并发标记清理收集器(CMS收集器)的主要目标就是:低应用停顿时间.该目标对于大多数交互式应用很重要,比如web应用.在我们看一下有关JVM的参数之前,让我们简要回顾CMS收集器 ...
- UseAdaptiveSizePolicy与CMS垃圾回收同时使用导致的JVM报错
系统在灰度环境上变更时发现JVM启动报错,详细检查JVM配置参数,发现新境了如下配置: -XX:+UseAdaptiveSizePolicy和-XX:+UseConcMarkSweepGC 初步猜想是 ...
随机推荐
- codeforces 626E. Simple Skewness 三分
题目链接 给n个数, 让你去掉一些数, 使得剩下的数的平均值-中位数的差值最大. 先将数组排序, 然后枚举每一个数作为中位数的情况, 对于每个枚举的数, 三分它的左右区间长度找到一个平均值最大的情况, ...
- 设置MAVEN_OPTS的推荐方法
运行mvn eclipse:eclipse时,经常会出现因为maven项目过大,导致内存不足java栈溢出的error,需要更改MAVEN启动内存 http://stackoverflow.com/q ...
- C++模板:qsort
void qsort(int l,int r){ int i,j,t,mid; mid=b[(l+r)>>1]; i=l; j=r; do{ while (b[i]<mid) i++ ...
- hdoj 3018 Ant Trip(无向图欧拉路||一笔画+并查集)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3018 思路分析:题目可以看做一笔画问题,求最少画多少笔可以把所有的边画一次并且只画一次: 首先可以求出 ...
- 黄聪:Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
去空格及特殊符号 s.strip().lstrip().rstrip(',') 复制字符串 #strcpy(sStr1,sStr2) sStr1 = 'strcpy' sStr2 = sStr1 sS ...
- invalid nib registered for identifier (重用符) - nib must contain exactly one top level object which must be a UITableViewCell instance'
通过xib创建cell的时候 一定要注意!!! 这个错误是在这个xib中在View同一层级出现了其他的控件,检查一下xib中左边的层级关系,让cell的view是唯一的控件就可以了,否则一执行 就会提 ...
- Maven模块聚合与继承
聚合 假如有account-email和account-persist两个模块,我们想要一次构建这两个项目,这时须要用到聚合. 聚合模块 package值必须为pom 必须有元素modules mod ...
- 前端性能监控系统ShowSlow
作者:zhanhailiang 日期:2014-11-14 1. 简单介绍 ShowSlow是开源的前端性能监控系统,提供了下面功能: 前端性能指标数据收集功能:ShowSlow原生提供了数据收集工具 ...
- asp.net传值
asp.net页面传至几种方法 Response.Redirect (或称 Query String 方式.URL方式) Response.Redirect("WebForm5.aspx&q ...
- ios7以上自定义导航栏标题的字体大小及颜色的方法
自定义导航栏的字体和颜色,只需要自定义一个lable,然后将lable添加到导航栏的titleview中就可以了 代码如下 UILabel *label = [[UILabel alloc] init ...