api大全-提供全网api api大全-提供全网api

拼多多,道门法则,小说网-api大全-提供全网api

布景

咱们上线Java服务的时分需求对其装备一些JVM参数,如堆空间巨细、虚拟机栈巨细、废物收回算法。关于年青代和老时代咱们能够装备不同的废物收回算法。在一些对rt要求很高的场景,服务不能有长期的卡顿,CMS就能够运用于此场景。

Concurrent Mark Sweep,是一款根据并发、运用符号铲除算法的废物收回算法,只针对老时代进行废物收回。

CMS搜集器作业时,GC作业线程和用户线程能够并发履行,以到达下降STW时刻的意图。

开起VM选项-XX:+UseConcMarkSweepGC,表明对老时代的收回选用CMS。

前置常识

STW

首要,咱们需求理清一个概念,即只要符号阶段才需求STW。

符号完结今后,需求铲除的目标现已确认,不管此刻是否发生新的废物,都不影响对这些目标的整理。也就是说,铲除阶段是能够规划成和用户线程并发履行的。

JVM在暂停的时分,需求选准一个机遇,因为JVM体系运转期间的复杂性,不或许做到随时暂停,因而引入了安全点(safepoint)的概念:程序只要在运转到安全点的时分,才能够暂停下来。

HotSpot选用自动中止的办法,让履行线程在运转期轮询是否需求暂停的标志,若需求则中止挂起。

HotSpot运用了几条矮小精粹的汇编指令便可完结安全点轮询以及触发线程中止,因而对体系功能的影响简直能够忽略不计。

可达性

可达性是指,假如一个目标会被至少一个程序中的可达目标经过直接或直接的办法引证,则称该目标是可达的。

更具体地说,一个目标满意以下两个条件之一,即被判定为可达的。

  1. 自身是根目标。根(root)是指由堆以外空间拜访的目标。JVM会将以下目标符号为根:
  2. 虚拟机栈(栈帧中的本地变量表)中引证的目标;

  3. 办法区中的类静态特点引证的目标;

  4. 办法区中的常量引证的目标;

  5. 本地办法栈中JNI的引证目标
  6. 被一个可达的目标引证。

CMS的几个阶段

CMS将可达性剖析分解成两个阶段:

  1. 仅扫描与根节点直接相关的目标;
  2. 持续向下扫描完一切目标。

因而,符号阶段也被拆分红两个阶段,即初始符号和并发符号。

CMS完好的搜集进程如下:

  • 初始符号(init-mark):仅扫描与根节点直接相关的目标并符号,这个阶段有必要STW, 因为跟节点数量有限,所以这个进程十分时间短。
  • 并发符号(concurrent-marking):与用户线程并发符号。这个阶段在初始符号的基础上持续向下追溯符号。在并发符号阶段,用户线程和符号线程并发履行,所以用户不会感受到中止。
  • 并发预整理(concurrent-precleaning):与用户线程并发进行。在并发符号阶段一些目标的引证现已发生了改动,precleaning会发现这些引证联系的改动,并将存活的目标符号。举个比如:假如线程A有一个指向目标X的引证,并将该引证传递给了线程B,CMS需求记载下线程B持有了目标X,即便线程A现已不存在了。precleaning是为了削减下一阶段“从头符号”的作业量,因为remark阶段会STW。
  • 从头符号(remark): remark阶段会STW。假如使用正在并发运转且在不断地改动目标引证,CMS则不能精确地确认某个目标是否存活。所以CMS会在remark阶段STW,然后获取一切引证联系的改动。
  • 并发整理(concurrent-sweeping):整理废物目标,这个阶段GC线程和用户线程并发履行。
  • 并发重置(concurrent-reset):重置CMS搜集器的数据结构,做好下一次履行GC使命的准备作业。

线上Full GC剖析

线上某服务的老时代装备了CMS,但却在gc.log发现接连Full GC的问题。JVM参数装备如下:

-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=68

参数的含义是:在老时代到68%的时分,会触发一次CMS GC,应该是呈现相似如下的日志:

T20:10:37.803+0800: 3246087.559: [CMS-concurrent-mark-start]
T20:10:38.463+0800: 3246088.220: [CMS-concurrent-mark: 0.661/0.661 secs] [Times: user=3.17 sys=0.56, real=0.66 secs]
T20:10:38.463+0800: 3246088.220: [CMS-concurrent-preclean-start]
T20:10:38.552+0800: 3246088.309: [CMS-concurrent-preclean: 0.069/0.089 secs] [Times: user=0.14 sys=0.04, real=0.09 secs]_
T20:10:38.552+0800: 3246088.309: [CMS-concurrent-abortable-preclean-start]

但线上环境的日志却呈现如下的状况:

老时代装备了900M,但却在只运用了50+M的时分触发了Full GC,并且是在时间短的时刻内接连触发。

装备了CMS却触发Full GC,有以下几种或许:

  • 大目标分配时,年青代不行,直接提升到老时代,老时代空间也不行,触发 Full GC(老时代还剩800+M,明显不或许)
  • 内存碎片导致(因为CMS是根据符号铲除算法的,一切会导致内存碎片,但经过grep -i "cms" gc.log,JVM没有触发过CMS收回,所以也不存在内存碎片的说法)
  • CMS GC失利导致(从gc.log并未找到concurrent mode failure的记载,扫除)
  • jmap -histo(人为履行该指令)

经笔者回想,在正午快12点的时分的确登录过线上机,履行过jmap -histo:live指令,经验证,手动履行jmap -histo:live,也的确会在gc.log呈现触发 Full GC的现象,问题得到验证。

作者:admin 分类:我们的头条 浏览:143 评论:0