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 初步猜想是 ...
随机推荐
- pexpect-pxssh-登陆Linux-执行命令
#!/usr/bin/python import pexpect import pxssh try: remote=pxssh.pxssh() hostname=raw_input('hostname ...
- MacOS下使用VMware5 破解 安装win7 ISO 激活
VMware5 下载 破解 以及win7 ISO版本的安装 激活VMware5 下载与破解参考方法http://www.macx.cn/thread-2060440-1-1.htmlVMware5 是 ...
- Bootstrap dropdown 使用
同样是2种方式 参考http://www.bootcss.com/javascript.html#dropdowns JS方式调用 http://www.w3resource.com/twitter- ...
- 在TreeWidget中增加右键菜单功能 以及TreeWidget的基本用法
TreeWidget 与 TreeView 中实现右键菜单稍有不同, TreeView 中是靠信号与槽 connect(ui->treeView,SIGNAL(customContextMenu ...
- 一劳永逸让windows 64位操作系统 禁止强制驱动签名
如何让WINDOWS7 64位直接加载“禁用强制驱动程序签名”方式启动 Windows Client 论坛 > Windows 7 问题 0 登录进行投票 因为开发需要,要装一台设备的驱动,但 ...
- Laravel + Xdebug 时需要注意的问题
[平台环境]64bit Win7 + Wamp2.5 (php 5.5, Apache 2.4.9) [Xdebug版本]php_xdebug-2.2.5-5.5-vc11-x86_64.dll 配置 ...
- 关于Unix时间戳
如何在不同编程语言中获取现在的Unix时间戳(Unix timestamp)? Java time JavaScript Math.round(new Date().getTime()/1000)ge ...
- CentOS, 高速设置ssh无password登录
首先.保证能够ping通 然后运行例如以下命令, master登录slave master上面运行例如以下指令: 2.4 确认本机sshd的配置文件(root) $ vi/etc/ssh/sshd_c ...
- hdu1715 大菲波数
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1715 Problem ...
- 深入理解java嵌套类和内部类
一.什么是嵌套类及内部类 能够在一个类的内部定义还有一个类.这样的类称为嵌套类(nested classes),它有两种类型:静态嵌套类和非静态嵌套类.静态嵌套类使用非常少,最重要的是非静态嵌套类,也 ...