为什么GC 异常,大家喜欢让Swap背锅呢

栏目: Java · 发布时间: 5年前

内容简介:01—在公司内部技术群里,经常有人时不时的问到服务某次GC时间突然很高,有什么办法排查。基本上每次都会有人怀疑会不会Swap导致的,先看看Swap,如果真的使用了Swap区域,基本上就会让Swap区域背锅了。

01

背景

在公司内部技术群里,经常有人时不时的问到服务某次GC时间突然很高,有什么办法排查。基本上每次都会有人怀疑会不会Swap导致的,先看看Swap,如果真的使用了Swap区域,基本上就会让Swap区域背锅了。

02

案例一:CMS GC时间飙升

有次群里有人给出一个case:CMS GC时间飙升,主要是remark阶段的处理时间太长,给出的日志如下:

为什么GC 异常,大家喜欢让Swap背锅呢

群里有人使用到了Swap区域。而对CMS GC如果有了解的话,想问的肯定是是不是加了“ -XX:+CMSScavengeBeforeRemark ”这个参数。在明确告知有这个参数。但是我在这个remark阶段并没有看到young gc,提问者就又截了一个全一点的日志,如下:

为什么GC 异常,大家喜欢让Swap背锅呢

感觉日志在remark之前并没有进行young gc,正常的加入 -XX:+CMSScavengeBeforeRemark ”参数日志应该如下:

为什么GC 异常,大家喜欢让Swap背锅呢

于是又让提问者确认一下,在remark时间正常的情况下是不是进行了young gc,在remark时间异常的情况下没有进行young gc,得到的答案是。 那么问题基本上就转化成了“为什么在remark之前没有进行young gc呢”

然后带着这个问题去Google基本上就比较容易找到答案了,基本可以概述为在执行JNI时候,有可能会导致JVM阻止执行young gc。可以参考:https://bugs.openjdk.java.net/browse/JDK-8057573

https://shipilev.net/jvm/anatomy-quarks/9-jni-critical-gclocker/

加入参数:+PrintJNIGCStalls可以验证该问题。

案例二:Young GC 时间飙升很高

这个笔者经历的一个case,监控&日志如下:

为什么GC 异常,大家喜欢让Swap背锅呢

为什么GC 异常,大家喜欢让Swap背锅呢

因为gc log中只能看到GC总时间看不到哪个阶段出现问题,所以把垃圾回收齐切换到G1,看到的log如下:

为什么GC 异常,大家喜欢让Swap背锅呢

发现Termination比较久,Object copy diff 太大导致的,也就是CPU繁忙程度不一致导致的,修改gc 线程数小于 cpu问题解决。

03

如何判断是不是Swap区域导致GC异常

如果JVM堆内内存大于等于系统内存的话,Java进程出现了大量使用Swap区域对GC影响确实比较大。如果发生GC抖动时,系统没有使用Swap区域或者 Java 进程没有使用Swap区域,就能排除Swap原因。

因为我司只对系统使用Swap区域的整体情况做了监控,并未对Java进程使用Swap区域做监控,GC抖动基本上是小概率事件,所以很难从监控做出判断的。

那么其他情况,如何大致判断出来是不是Swap导致的GC异常呢?

首先,我们得了解Swap相关的基本知识。

Swap区域主要解决内部不足的问题,把部分硬盘当做虚拟内存使用。

Swap中最关键的系统参数:vm.swapiness(0-100), 该参数值越小表示当内存不足时,倾向于通过回收cache区域,而不是把进程内存交换到Swap区域。所以该值应该设置小一点就能减少Swap可能对GC产生的影响,比如我司统一默认设置为1。

Swap内存回收算法使用的是LRU算法,他会标记处活跃页面和非活跃页面,也就是说如果内存一直被使用基本上常驻内存,不会被交换到Swap。

GC的哪些阶段可能受Swap影响

young gc

young gc的特色是较为频繁,基本上每分钟都会多次。young gc主要有两个阶段,一个是扫描阶段、一个是对象复制阶段。 扫描阶段会从 根集合扫描标记 Eden、From中的存活对象,然后对象复制阶段把存活对象copy到To区域中去。

复制阶段: 因为young gc较为频繁就会导致 Eden、From、To区域不太可能被置换到Swap区域,所以 复制阶段不太可能受到Swap区域影响;假设young gc不频繁,那么在刚刚经历了 扫描阶段, Eden、From 肯定会在内存中,只有To区域有可能会受到Swap影响。

相比较于复制阶段, 扫描阶段就相对复杂一点。这主要跟根集合有关系,young gc的根集合主要有线程上下文、old区域、Class、JNI引用等,像JNI引用、Class等长时间不使用 有可能被OS置换到Swap。所以该阶段有可能因为Swap影响GC。

cms gc

cms gc主要分为:初始标记、并发标记、并发预清理、重新标记、并发清理等阶段,只有初始标记和重新标记会stop the world,所以我们只需要关注这两个阶段即可。

初始标记:该阶段标记GC Roots能直接关联到的对象。所以该阶段和young gc的扫描阶段类似,也有可能因为Swap影响到GC。

重新标记: 由于在并发标记和并发预清理这个阶段,用户线程和GC 线程并发,假如这个阶段用户线程产生了新的对象,总不能被 GC 掉吧。这个阶段就是为了让这些对象重新标记。在这个阶段访问到的内存一定是之前刚刚访问过的,所以这个阶段不太可能由Swap区域导致GC异常。

04

总结

对于CMS GC,如果在remark阶段异常行为而InitialMark是正常的,基本上可以排除Swap导致的GC,young gc在copy阶段异常而Root Scaning正常也基本上可以排除Swap因素。

我想大家喜欢让Swap背锅的原因有两个:

  • 对Swap如何影响GC以及可能影响到GC哪些阶段不太了解;

  • GC时间异常情况下,确实较难分析和排除;必须要对GC的具体过程,GC工具等有较为深入的了解。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

黑客与画家

黑客与画家

[美] Paul Graham / 阮一峰 / 人民邮电出版社 / 2011-4 / 49.00元

本书是硅谷创业之父Paul Graham 的文集,主要介绍黑客即优秀程序员的爱好和动机,讨论黑客成长、黑客对世界的贡献以及编程语言和黑客工作方法等所有对计算机时代感兴趣的人的一些话题。书中的内容不但有助于了解计算机编程的本质、互联网行业的规则,还会帮助读者了解我们这个时代,迫使读者独立思考。 本书适合所有程序员和互联网创业者,也适合一切对计算机行业感兴趣的读者。一起来看看 《黑客与画家》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具