垃圾收集器CMS-JVM(十一)

Jvm类的创建过程包括类的加载,类的验证,准备,分析,初始化。

验证是不是.class文件。

准备过程则是先赋值初始化的值,并不是直接赋值原始值。

分析比较复杂,会有静态链接处理和动态链接处理。

最后就是类的初始化。

前面还有一个类的加载没说,类的加载则需要考虑到双亲委派,有三个类自带的核心加载器,bootStrap加载器,扩展加载器,app加载器,后面则有自定义加载器。

前面则说了垃圾收集器有复制,标记整理,标记清除。Serial,parallel,ParNew。

垃圾收集器ParNew-JVM(十)

  • CMS(Concurrent Mark Sweep)

cms收集器是一种考虑用户体验的收集器,以最短停顿为目的而设计的,它是第一个真正意义上实现用户线程与垃圾收集器并行工作。从mark sweep可以看出来它是标记清除算法,整体来说比前面介绍的都复杂点。

  1. 初始标记 :暂停所有其他用户线程STW,并可达性算法记录GC roots直接能引用的对象,速度很快,用户基本无感知。

(因为速度必须要快,所以要STW,不然一直新增对象一直标记难以保证速率)

  1. 并发标记:并发标记就是开始遍历整个对象图的过程,这个过程耗时长,但不会暂停线程(不需要STW),垃圾线程和用户线程一起执行。

已经标记过的状态可能会发生变化,之前是垃圾变为对象,是对象的变为垃圾。

初始标记只标记一个直接引用对象,并发标记会从这个引用对象一直找,直到找完堆。

(为了用户体验,耗时长,所以不STW)

  1. 重新标记 :重新标记主要是为了修改并发标记期间改变的对象状态,这个耗时会稍微长点,但远远比并发标记耗时短,这里主要用到三色标记里的增量更新算法
  2. 并发清理:开启用户线程,同时GC线程对未标记的做清理。新增的对象则标记为黑色(三色标记)不做任何处理。
  3. 并发重置:重置本次GC过程的标记数据。

其中并发标记占用时间最长,约占收集过程中百分之80的时间。

整个STW只有初始标记和重新标记部分,这两部分耗时非常低,所以用户体验基本无感知。

可以看出来cms是一个优秀的垃圾收集器,优点是:并发收集、停顿低。但他也是有缺点的:

  1. 对CPU资源敏感,会和服务抢资源。
  2. 浮动垃圾无法清理。(前面说了在并发标记和并发清理阶段是和用户线程并行的,这时候有新的用户对象则不会清理,会等到下次GC再清理)
  3. 因为他使用的标记清除,所以导致会有大量碎片,必须和JVM参数一起用

-XX:UseCMSCompactAtFullCollection

可以让jvm在执行完标记清除后整理碎片空间。

  1. 执行过程又不确定性,当垃圾还没收集完,用户线程又有新的对象进入,特别是并发阶段并发标记和并发清理,触发fullGC,这时候会触发concurrent mode failure,此时会进入全部的STW,用Serail old垃圾收集器。

(ParNew并发处理年轻代,CMS并发处理老年代,内存不够用,于是就用serial old单线程运行)

那么如何避免垃圾收集器用serial old收集呢?

1、启动CMS参数:-XX:+UseConcMarkSweep

(jdk1.8是可以用的,1.9之后则会提示过时(可以用),默认用的G1)

  1. -XX:+ConcGCThreads:并发线程数
  2. -XX:+UseCMSCompactAtFullCollection:fullGC之后减少碎片,整理。
  3. -XX:+CMSFullGCsBeforeCompaction:多少次fullGC才会压缩整理碎片,默认是0。
  4. -XX:+CMSInitiatingOccupancyFraction:当老年代使用达到该比例才出发fullGC,默认是达到百分92才fullGC。

(这个参数就是解决执行的不确定性,防止concurrent mode failture,保证剩余空间继续收集,如果系统大对象太多,则考虑调整小,调整为90,80或者75)

  1. -XX:+UseCMSInitiatingOccupancyOnly:只使用设定的回收阀值,

与-XX:+CMSInitiatingOccupancyFraction连用,如果不指定,则只在第一次生效,后续则会自动调整,比较智能化。

  1. -XX:+CMSScavengeBeforeRemark:配置之后,会在fullGC前启动一次minor GC,会提高效率,先减少一部分垃圾对象。
  2. -XX:+CMSParallellnitialMarkEnabled:表示初始化也并行,缩短STW。
  3. -XX:+CMSParallelRemarkEnabled:重新标记的时候也是多线程并行,缩短STW。
相关推荐
小江的记录本2 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
思麟呀9 小时前
C++11并发编程:call_once一次性执行+atomic原子类型+CAS无锁编程+自旋锁
linux·开发语言·jvm·c++·windows
Fanfanaas11 小时前
C++ 继承
java·开发语言·jvm·c++·学习·算法
周杰伦fans13 小时前
C# 异常继承深度解析:从设计原则到 sealed 关键字的奥秘
java·jvm·c#
川石课堂软件测试13 小时前
零基础小白如何学习自动化测试
python·功能测试·学习·测试工具·jmeter·压力测试·harmonyos
小L写Java14 小时前
第三章:Java 内存模型 (JMM) 与运行时数据区
java·jvm
川石课堂软件测试14 小时前
作为一名测试工程师如何学习Kubernetes(k8s)技能
学习·测试工具·容器·职场和发展·kubernetes·测试用例·harmonyos
Luminbox紫创测控15 小时前
太阳模拟器自动化测试系统:稳态、脉冲、闪光光源的控制与数据采集
人工智能·测试工具·测试标准
一氧化二氢.h15 小时前
图中元件的执行顺序
测试工具·jmeter