代码编织梦想

关于serial,parnew,parallel等回收器的介绍可以参考上一篇jvm垃圾回收算法以及垃圾回收器,如何选择_bjzw的博客-CSDN博客

下面具体介绍一下cms,jdk8之后就已经废弃了cms垃圾回收器,为什么要还要详解cms呢

        首先,cms的回收思想需要我们了解

        其次,G1回收器也复用了cms的一部分思想

一、CMS回收

        CMS是在老年代的垃圾回收算法,全程为Concurrent Mark Sweep,即标记并行算法。具体有六个步骤,初始标记、并发标记、并发预处理、重新标记,并发清理、并发重置为了描述清楚,别处找了个图

       

         1、初始标记

                初始标记阶段会触发stop the world,标记所有CGRoot直接关联的对象,以及年轻代对象对老年代对象的引用,间接关联的在下一阶段。

        2、并发标记

                与用户线程并发执行,会遍历上一阶段标记过的对象进行遍历,并将这些对象所有的引用进行标记。第一,第二阶段就是要将老年代,新生代的里面存活的对象找出来

                由于是并发执行,所以会导致有遗漏的老年代对象实例,如以下情况:年轻代部分对象移动至老年代,老年代对象引用发生变更,还有一些大对象直接进入老年代。

上面三种情况的对象所在的卡表(card table)被标记为dirty。

虽然CMS收集的是老年代的对象,但是会扫描新生代。

                什么叫卡表呢?

                        就是将老年代的空间分成521B分解成若干张卡,卡表本身是个数组,数组中的每个元素对应一张卡,当有老年代引用新生代的对象时,对应的卡表的元素被标记为dirty(脏)如下图

                 并发标记就是通过卡表标记dirty,后期就不会再对老年代整个扫描了。

        3、并发预清理

                这个阶段是标记老年代存活的对象,尽量让重新标记阶段的STW时间短,这个阶段也会扫描老年代和新生代。

        4、重新标记

                这个阶段会STW,标记老年代的存活对象,这个时候扫描新生代的对象、GCRoots和之前标记为dirty的卡表老年代对象。

        5、并发清理

                清理未被标记的对象,释放内存空间

        6、并发重置

                CMS内部进行重置回收器状态,准备为下一个周期做准备。

二、如何配置CMS回收器

     1、CMS相关JVM参数
        -XX:+UseConcMarkSweepGC    激活CMS收集器。默认情况下使用ParNew + CMS + Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现“Concurrent Mode Failure”失败后的后备收集器使用。

        -XX:CMSInitiatingOccupancyFraction={x}    在老年代的空间被占用{x}%时,调用CMS算法对老年代进行垃圾回收。
        -XX:CMSFullGCsBeforeCompaction={x}    在进行了{x}次CMS算法之后,对老年代进行一次compaction
        -XX:+CMSPermGenSweepingEnabled & -XX:+CMSClassUnloadingEnabled    让CMS默认遍历永久代(Perm区)
        -XX:ParallelCMSThreads={x}    设置CMS算法中并行线程的数量为{x}。(默认启动(CPU数量+3) / 4个线程。)
        -XX:+ExplicitGCInvokesConcurrent    用户程序中可能出现利用System.gc()触发系统Full GC(将会stop-the-world),利用这个参数可以指定System.gc()直接调用CMS算法做GC。
        -XX:+DisableExplicitGC    该参数直接让JVM忽略用户程序中的System.gc()

  2.注意事项

        -XX:+UseParNewGC, -XX:+UseConcMarkSweepGC
分别表示使用并行收集器 ParNew 对新生代进行垃圾回收,使用并发标记清除收集器 CMS 对老年代进行垃圾回收。

        -XX:ParallelGCThreads, -XX:ParallelCMSThreads
分别表示 Young GC 与 CMS GC 工作时的并行线程数,建议根据处理器数量进行合理设置。

        -XX:+UseCMSCompactAtFullCollection
由于 CMS GC 会产生内存碎片,且只在 Full GC 时才会进行内存碎片压缩(因此 使用 CMS 垃圾回收器避免不了 Full GC)。这个参数表示开启 Full GC 时的压缩功能,减少内存碎片。

        -XX:+UseCMSInitiatingOccupancyOnly
        -XX:CMSInitiatingOccupancyFraction
        -XX:CMSInitiatingOccupancyFraction 表示触发 CMS GC 的老年代使用阈值,一般设置为 70~80(百分比),设置太小会增加 CMS GC 发现的频率,设置太大可能会导致并发模式失败或晋升失败。

        -XX:+UseCMSInitiatingOccupancyOnly 表示 CMS GC 只基于  CMSInitiatingOccupancyFraction 触发,如果未设置该参数则 JVM 只会根据  CMSInitiatingOccupancyFraction 触发第一次 CMS GC ,后续还是会自动触发。建议同时设置这两个参数。

        -XX:+CMSClassUnloadingEnabled 表示开启 CMS 对永久代的垃圾回收(或元空间),避免由于永久代空间耗尽带来 Full GC。

        -XX:+CMSParallelRemarkEnabled 开启降低标记停顿。

A、提升失败(promotion failed)
在 Minor GC 过程中,Survivor Unused 可能不足以容纳 Eden 和另一个 Survivor 中的存活对象, 那么多余的存货对象将被移到老年代, 称为过早提升(Premature Promotion)。 这会导致老年代中短期存活对象的增长, 可能会引发严重的性能问题。

再进一步,如果老年代没有足够的空间放下这些存活对象,或者老年代有足够的空间,但是由于碎片较多,这时如果新生代要转移到老年带的对象比较大,所以,必须尽可能提早触发老年代的CMS回收来避免这个问题(promotion failed时老年代CMS还没有机会进行回收,又放不下转移到老年带的对象,因此会出现下一个问题concurrent mode failure,需要stop-the-wold GC- Serail Old)。

解决办法:

        针对一些大的朝生熄灭的对象,Surivor空间存放不下,就会存放到老年代,针对这种情况,可以扩大Survivor空间。

        老年代空间碎片,无法放下大对象,就在进行一定次数的Full GC(标记清除)的时候进行一次标记整理算法。

B、并发模式失败(concurrent mode failure)
由于cms的无法处理浮动垃圾(Floating Garbage)引起的。这个跟cms的机制有关。cms的并发清理阶段,用户线程还在运行,因此不断有新的垃圾产生,而这些垃圾不在这次清理标记的范畴里头,cms无法在本次gc清除掉,这些就是浮动垃圾。
由于这种机制,cms年老代回收的阈值不能太高,否则就容易预留的内存空间很可能不够(因为本次gc同时还有浮动垃圾产生),从而导致concurrent mode failure发生。可以通过-XX:CMSInitiatingOccupancyFraction的值来调优。

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m554062212/article/details/127712402

深入理解jvm虚拟机3:垃圾回收器详解_黄小斜的博客-爱代码爱编程

转自 JavaDoop HotSpot JVM 垃圾回收器 更新时间:2018-03-28 关于 JVM 内存管理或者说垃圾收集,大家可能看过很多的文章了,笔者准备给大家总结下。这算是系列的第一篇,接下来一段时间会持续更新。 本文主要是翻译《Memory Management in the Java HotSpot Virtual

jvm 垃圾回收算法及回收器详解_抽离的心的博客-爱代码爱编程

原文地址:http://www.importnew.com/26383.html 1.JVM垃圾回收       JVM中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此内存垃圾回收主要集中于 java 堆和方法区中,而在程序运行期间这部分内存的分配和使用都是由JVM动态处

JVM之垃圾回收器:CMS垃圾回收器-爱代码爱编程

文章目录 简介CMS工作原理总结CMS变化Reference 简介 CMS垃圾回收器简介JDK1.5时期,HotSpot推出了一款在强交互应用中有划时代意义的垃圾收集器:CMS(Concurrent-Mark-Sweep)收集器,这款收集器是HotSpot虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作回收

JVM垃圾回收器详解-爱代码爱编程

JVM垃圾回收器详解 一 垃圾回收器的组合关系 7款垃圾回收器与垃圾分代之间的关系垃圾收集器的组合关系 说明: ① 两个收集器间有连续表明它们可以搭配使用 ② 其中Serial Old作为CMS出现Concurrent Mode Failure失败的后备预案 ③ 红色虚线由于维护和兼容性测试的成本,在JDK8时将Serial+CMS,ParNew+Se

JVM的各种垃圾收集器详解(CMS、G1)-爱代码爱编程

我们可以把垃圾回收器分为3类 串行、吞吐量优先、响应时间优先 其中,串行是单线程,吞吐量优先和响应时间优先是多线程 本文重点讨论的是分代收集器,ZGC会另外做一个文章专门讲解 1 串行(单线程) Serial收集器(复制算法)——新生代 Serial Old收集器(标记-整理算法)——老年代 单线程对内存较小,适合个人电脑采用复制算法-新生代

JVM 垃圾收集器 G1 详解-爱代码爱编程

G1 垃圾收集器 Opening words 这是一篇欠了自己很久的文章吧,一直想写一篇关于垃圾收集器 G1 的总结文章,却迟迟没有下笔哈哈,本篇将深入浅出带大家看看 G1 究竟给我们程序的垃圾收集带来了什么。 G1 简介 The Garbage-First (G1) 是服务器类型的垃圾收集器,它适用于大内存的垃圾收集处理并且可以控制垃圾收集 ST

JVM垃圾回收与调优详解-爱代码爱编程

1.JVM内存分配与回收 1.1 对象优先在Eden区分配 大多数情况下,对象在新生代中 Eden 区分配。当 Eden 区没有足够空间进行分配时,虚拟机将发起一次Minor GC。我们来进行实际测试一下。 在测试之前我们先来看看 Minor Gc和Full GC 有什么不同呢? 新生代GC(Minor GC):指发生新生代的的垃圾收集动作,Minor G

JVM 垃圾回收算法和 CMS 垃圾回收器-爱代码爱编程

微信公众号:运维开发故事,作者:老郑 本文核心主要是讲述:JVM 中的几种垃圾回收算法理论,以及多种垃圾收集器,并且详细参数 CMS 垃圾收集器的实现、优缺点等,最后也会解释一下三色标记法与读写屏障。 垃圾收集算法 垃圾收集算法.png 分代收集理论 (Generational Collection) 当前商业虚拟机的垃圾收集都是

JVM 垃圾回收详解-爱代码爱编程

JVM 垃圾回收 1.概述 JVM 会自动帮程序员进行垃圾回收,并不需要程序员手动的进行垃圾回收(C++等语言需要自己手动回收垃圾),了解 JVM 的垃圾回收,可以帮程序员写出占用内存更小、更高效的程序。 1.1 什么是垃圾? 垃圾是指运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。 1.2 什么区域需要进行垃圾回收 JVM 的

详解JVM 的垃圾回收算法和垃圾回收器-爱代码爱编程

开篇 我们知道JVM的垃圾回收机制实际上是对JVM内存的操作,回收的目的是为了避免内存溢出和内存泄漏的问题。而JVM内存由方法区、堆、虚拟机栈、本地方法栈以及程序计数器5块区域组成,虚拟机栈、本地方法栈、程序计数器是随着Java线程建立而建立,当Java 线程完成之后这三个部分的内存就会被释放掉。 而方法区和堆属于共有线程,是随着JVM启动而建立的

JVM垃圾回收器之深入理解CMS垃圾回收器-爱代码爱编程

前言 CMS垃圾回收器是本人理解最深刻的JVM垃圾回收器,CMS是首个可以与用户线程并发的低停顿收集器。随着技术的发展、JDK的更新迭代,CMS这个曾经被寄予厚望的并发垃圾回收器已经慢慢要被时代抛弃了,后面出来的G1,ZGC已经盖过了CMS的光芒,JDK9之后CMS甚至被抛弃为不建议使用。但是后来者都是踩在CMS肩膀上迭代的,你可以在G1中看到大量CMS

JVM垃圾回收详解-爱代码爱编程

1:JVM内存模型 1 jdk 1.8 里主要是 分成了 堆(新生代【eden,s0,s1】,老年代,元空间),方法区,程序计数器,虚拟机栈,本地方法栈 2 对象和共享变量放到堆里,类信息,方法和字符串常量池放到方法区里,栈里面都是内存地址值和局部变量 3 本地方法栈——私有,存储线程的本地方法调用信息,也是主要是栈帧。是c 语言实现 4 程序计数器——

jVM 垃圾回收器之CMS详解-爱代码爱编程

一、CMS定义和特点 CMS收集器是一种以获取最短停顿时间为目标的收集器。它的优点是并发收集和低停顿。 二、CMS 基于哪种GC算法实现的 CMS主要是基于标记清除算法实现的 三、标记清除算法详解 算法主要是分为 标记 和 清除 两个阶段实现,在标记阶段 从 GC root出发通过可达性分析将需要被清除的对象标记起来,在清除阶段全部进行清除,这种算法有两个

jvm-爱代码爱编程

前景回顾 堆内存逻辑分区 Eden区,survivor区 old区 除Epsilon ZGC Shenandoah之外的GC都是使用逻辑分代模型 G1是逻辑分代,物理不分代 除此之外不仅逻辑分代,而且物理分代 标记清