zoukankan      html  css  js  c++  java
  • 一次线上FullGC问题记录

    ​ 标题采自:英雄联盟-瑞文:断剑重铸之日,骑士归来之时!

    断剑

    ​ 前两天早上在挤地铁的时候看到小组群里,主管发了好多消息,打开来一看,说是XX项目自从22号发版后,每天晚上就疯狂Full GC,让我们查一下什么原因,嘻嘻嘻,一开始听到,心里窃喜,为什么呢。因为自己以前对jvm也有些了解,不过都只是纸上谈兵罢了。现在刚好有机会,到公司就和小伙伴开始排查。以下是full gc的图片

    ​ 图 - 1.0


    ​ 图 - 2.0

    ​ 图 - 3.0

    ​ 当然这是运维给出来的,一开始看到这个,我是懵逼的,这tm是什么。接着往下看:运维又给出了如下图的dump日志

    ​ 图- 4.0

    ​ 我心里又问,这tm是什么。哇,一脸懵逼的我,又去补了jvm的内存模型。

    重铸

    ​ 就在我补给的时候,有个大佬已经发言了,

    ​ 图 -5.0

    ​ 是不是感觉找到问题的来源了,就这有结束了,嘻嘻嘻。然后心里一阵窃喜,还好是老代码。不是我写的。但是事实却没有结束,为什么了。接着往下看:

    ​ 又一位大佬说:图-6.0 应该就是这块了

    ​ 图- 6.0

    ​ 主管又说:虽然是老代码,但是以前没发生过这样的问题,但是自从22号发版后就开始了,她就查看了一下22号有关AssostantsDto 这块有关的代码,并截图发了出来


    ​ 图-7.0

    ​ 看到发出来的这段,上面有我的署名 ouyangkang modify,我先是脸部发烫,然后大脑空白,接着回魂。我????? 写的。emmmm............。有点印象,这段代码有问题?看下绿色的那段我改的代码,

    首先获取到一个list对象,遍历该list,给list容器中的对象赋值,并重新把该对象添加list容器中,乍看一下,没问题啊,这段代码。emm............................

    仔细再看下绿色的那段我改的代码:

    首先获取到一个list对象,遍历该list,给list容器中的对象赋值,并重新把该对象添加list容器中。等等,重新添加到list容器中,那么该list容器的大小不就也更大吗,那么又会进行一次循环,这不发生了死循环吗。哇!! 这就很有意思了,我的锅,我的锅。

    那么怎么改呢:

    第一种方案:直接去掉list.add(i,assistantsDto)。因为你堆list中的对象写入内容的话,list中的对象引用的地址是不会改变的。

    第二种方案:list.set(i,assistantsDto) 将改dto替换。

    项目重新发版,果然这几天xx项目再也没有出现频繁的Full GC了。

    之日

    图-2.0 解释

    ​ 解释断剑中图中含义:如果能够看懂前面几张图的这节就可以跳过了。图1.0就不解释了,首先图-2.0中第一行

    60208.152(时间戳),[Full GC(Ergonomics)(解释:发生了什么GC)4035169K(解释:jvm堆中内存已用大小)->3635904(解释:经过full gc回收堆中内存后,堆中还剩余的内存大小) (4178944K(解释:jvm堆的总内存大小))]
    

    从图-1.0 中可以看出,经过一个full gc后,堆中可用内存还是不多,并且发生了很多次full gc。我们都知道full gc就是stop the word 连续的full gc 。那么就导致这个项目不再对外提供服务了。

    GC 策略

    ​ 大概说一下GC有哪几种回收策略,详情网上都有,自行查看,我就不写了(偷懒),算了,我还是写了点。

    ​ minor GC: 发生在年轻代。

    ​ 一开始:当eden区对象写满的时候,发生minor GC,把存活对象放到S0,释放其他对象所占内存,继续运行,eden区又写满了,发生minor GC,回收eden区和S0区存活对象,把存活对象防止S1,释放其他对象所占内存。eden区又写满了,发生minor GC,回收eden区和S1区存活对象,把存活对象防止S0,释放其他对象所占内存。反反复复,比较老一点的对象就放到了老年代。

    ​ major GC:发生在老年代:eg: 当发生minor GC 的时候,想把存活的老对象放到老年代,但是没有这么大的连续内存空间,此时就会发生major GC

    ​ full GC: 发生在年轻代和老年代 : eg: 当老年代和新生代内存都写的快满了的时候就会发生full GC|

    JVM内存模型

    ​ 大概说一下JVM内存模型:下次写篇blog单独介绍一下吧 。先欠着

    图-3.0 解释

    ​ 我截取部分进行解释:

    S0C :Survivor0 可用内存大小 。 S1C: Survivor1可用内存大小

    S0U:Survivor0 已用内存大小 S1U :Survivor1已用内存大小

    EC: eden可用内存大小 EU:eden 已用内存大小

    OC: 老年代可用内存大小 OU:老年代已用内存大小

    MC:方法区可用内存大小 MU:方法区已用内存大小

    CCSC :压缩类空间内存大小 CCSU:压缩类空间已用内存带下

    YGC: 年轻代垃圾回收次数 YGCT:young GC消耗的时间

    FGC:full GC 回收次数 FGC:full GC 消耗的时间

    GCT : GC 消耗的时间

    图-4.0 解释

    ​ 用mat工具打开jump文件所得到的,首先网上下载 mat,选择适合你电脑系统的。至于怎么操作,下次单独拎出来介绍。

    其实我还研究了一点jvm虚拟机参数设置,GC日志打印,本地线程监控,我想留到下一篇博客再介绍吧。谢谢

    如果我不写骑士归来之时,强迫症是不是会很难受。那么就推荐一下,留个言,我大声讲出来。

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    《EffectiveJava中文第二版》 高清PDF下载
    《MoreEffectiveC++中文版》 pdf 下载
    《啊哈c语言》 高清 PDF 下载
  • 原文地址:https://www.cnblogs.com/Krloypower/p/10082017.html
Copyright © 2011-2022 走看看