垃圾收集器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。
相关推荐
金銀銅鐵3 小时前
带您看懂字节码指令(三):一行加法里有什么
java·jvm
jyOverQ7 小时前
从零学 JVM(七):垃圾收集器详解——Serial、ParNew、Parallel、CMS 与 G1
java·jvm
金銀銅鐵1 天前
带您看懂字节码指令(三):同一行加法,为什么有四种指令
java·jvm
火云代理1 天前
同一个网站,有的网络能打开、有的打不开?认识 IPv4 与 IPv6 的访问差异
服务器·网络·网络协议·tcp/ip·测试工具·php·状态模式
jyOverQ1 天前
从零学 JVM(五):垃圾回收机制——对象存活判断与 GC Roots
jvm
金銀銅鐵1 天前
一个 4 个常量的枚举,Kotlin 在字节码里生成了什么
jvm·kotlin
2301_808414381 天前
Linux线程的同步与互斥
jvm
曲径海盗2 天前
Try-Except怎么用,3个追问解答在自动化下的应用
java·jvm·oracle
freejackman5 天前
【工程化】从“单兵作战”到“多引擎架构”:基于门面模式的重构实战
大数据·数据库·hive·sql·测试工具·设计模式·架构
寂寞的船5 天前
【Unity知识速递】第10期 Unity GC 零分配实战:从 UnityEngine.Pool 到手动 GC 控制的全链路优化
jvm·unity·c#·游戏引擎·lucene