<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          記一次CMS GC耗時(shí)46.6秒的排查過(guò)程與解決方法

          共 4366字,需瀏覽 9分鐘

           ·

          2023-08-20 01:30

          你知道的越多,不知道的就越多,業(yè)余的像一棵小草!

          你來(lái),我們一起精進(jìn)!你不來(lái),我和你的競(jìng)爭(zhēng)對(duì)手一起精進(jìn)!

          編輯:業(yè)余草

          來(lái)源:juejin.cn/post/7257048145233543229

          推薦:https://t.zsxq.com/11wE4iuIb

          自律才 能自由

          早上7.16分左右 ,有個(gè)服務(wù)發(fā)生了緊急告警,很多接口超時(shí),出于 「客戶(hù)的投訴」 和老板的給出的壓力,我開(kāi)始了排查之旅~~~

          64792d1ae1c815ecbb423e0083775c38.webp
          ?

          【排查到最后發(fā)現(xiàn),并不是這些超時(shí)的接口都有問(wèn)題,而是 「其中某一個(gè)接口影響了整個(gè)服務(wù)」,只要是這個(gè)服務(wù)上的接口,都有可能超時(shí)、異常、 等不正?,F(xiàn)象】

          ?

          看下現(xiàn)象

          「釘釘群告警:」

          d8dfeeba5bbcee6bd81f2f4cbb4fbb5d.webp釘釘群告警

          「下圖為 告警機(jī)器JVM 監(jiān)控面板:」

          6b64b8c06da249099f8abc323c659c69.webpJVM 監(jiān)控面板

          觀察監(jiān)控面板看到的現(xiàn)象

          「CMS GC單次耗時(shí)過(guò)長(zhǎng):」

          可以看到 CMS GC耗時(shí)46.6秒! ,我們知道CMS收集器是作用于老年代的垃圾收集器,他有四個(gè)階段,其中階段1 (初始標(biāo)記)階段4(重新標(biāo)記)會(huì)發(fā)生 「stop-the-world」即暫停所有應(yīng)用線程),如果這 46.6 秒正好是這兩個(gè)階段中的某一個(gè),那么,相當(dāng)于整個(gè)服務(wù)在這46.6秒內(nèi),不處理任何的請(qǐng)求,只專(zhuān)注于垃圾回收的工作,整個(gè)服務(wù)高延遲,低吞吐!我去!那還怎么玩???這種情況下,該服務(wù)就算所有接口都超時(shí),也不足為奇呀!

          「線程數(shù)量:」 線程數(shù)量陡增

          「線程狀態(tài):」 waiting 和 time_waiting的線程陡增

          「cpu情況:」 cpu使用率很高

          觀察后得出結(jié)論 & 排查方向

          1. 一、「得出結(jié)論:」 觀察上邊的監(jiān)控信息,可以得出結(jié)論:單次 CMS GC 耗時(shí)太長(zhǎng)!,線程,cpu 都不正常!
          2. 二、「排查方向:」 我的第一直覺(jué)就是有地方發(fā)生了內(nèi)存泄露(因?yàn)閾?jù)我的經(jīng)驗(yàn)來(lái)看, 內(nèi)存泄露很有可能和 GC 相關(guān)聯(lián)),或者哪個(gè)地方分配了大對(duì)象。由于線程信息當(dāng)時(shí)沒(méi)有dump下來(lái)(不清楚啥原因沒(méi)搞下來(lái)),并且我猜測(cè)根因與 內(nèi)存泄露 或者 大對(duì)象分配 方面更接近,所以我的排查方向「沒(méi)往」 「線程」 那個(gè)方向走,而是 「著重觀察堆棧和GC信息」。
          ?

          光猜沒(méi)用呀,于是找運(yùn)維同學(xué)要了堆棧信息,之后的排查流程大概是這樣 :

          dump堆棧文件-> 使用 MAT 工具分析-> 仔細(xì)觀察各項(xiàng)指標(biāo) -> 定位問(wèn)題代碼

          ?

          拿到堆棧文件并使用 MAT 分析

          找運(yùn)維同學(xué)拿到堆棧信息文件 以.dump結(jié)尾的,如下:

          8d90ef1aa014608fd3e347237e14987a.webpMAT 分析

          「拿到文件后解壓,并且后綴 改成 .hprof 否則mat工具不識(shí)別,導(dǎo)入不進(jìn)去?!?/strong>

          說(shuō)到dump文件其實(shí)有很多個(gè)工具都可以分析,如下:

          • 簡(jiǎn)易:JConsole、JVisualvm、HA、GCHisto、GCViewer
          • 進(jìn)階:MAT、JProfiler

          由于之前我使用過(guò)mat,所以我還是使用mat來(lái)排查,先簡(jiǎn)介下mat:

                
                MAT(Eclipse Memory Analyzer)是一種快速且功能豐富的Java堆分析器,它幫助查找內(nèi)存泄漏。
          使用內(nèi)存分析 器分析具有數(shù)億個(gè)對(duì)象的高效堆轉(zhuǎn)儲(chǔ),快速計(jì)算對(duì)象的保留大小,查看誰(shuí)在阻止垃圾收集器收集對(duì)象,
          運(yùn)行報(bào)告以自動(dòng)提取泄漏嫌疑。 官網(wǎng)地址https://www.eclipse.org/mat,
          下載地址為https://www.eclipse.org/mat/downloads.php。我們可以在下載 頁(yè)面看到:MAT可以獨(dú)立運(yùn)行,
          也可以通過(guò)插件的形式在Eclipse中安裝使用,具體的安裝過(guò)程就不再這里介紹了,我是下載的獨(dú)立運(yùn)行 的程序包。

          導(dǎo)入:

          2977bd9ffe197b1baa8758a0ffbe67a8.webp導(dǎo)入分析

          導(dǎo)入后,一般都會(huì)自動(dòng)分析,需要一定時(shí)間,分析完后如下:

          ca43f3c2b040fe403afdf18f20191ba1.webp自動(dòng)分析

          看懂 MAT工具 的分析報(bào)告

          ?

          工欲善其事必先利其器,接下來(lái)我們看看這個(gè)工具的一些常用操作,以及分析了哪些指標(biāo)?

          ?

          Histogram: 直方圖(里邊包含了每個(gè)類(lèi)所對(duì)應(yīng)的對(duì)象個(gè)數(shù),以及所占用的內(nèi)存大小)

          acb1fd918f2c63e6fdae762255562063.webp分析報(bào)告

          Dominator Tree: 可以看到哪些對(duì)象占用的空間最大以及占比 (常用于尋找大對(duì)象)

          71208283eabdcd392260cdaa0ac672ab.webpDominator Tree

          Leak Suspects: 可疑的內(nèi)存泄露 分析,餅狀圖很直觀(排查內(nèi)存泄露利器)。

          c2a1537ec071825788acb9e16fd639c7.webpLeak Suspects

          Top components:** 對(duì)占用 堆內(nèi)存 超過(guò) 整個(gè)堆內(nèi)存1% 大小的組件做的一系列分析

          可以看到他是從多個(gè)角度(如:對(duì)象,類(lèi)加載器,包)來(lái)分析占比超過(guò)1%的組件的。

          39c9333c3c65594c7de8c3a504879361.webpTop components

          Top consumers:** 列出最昂貴的對(duì)象

          277180a329c256492160093e6d99ec0f.webpTop consumers

          可以看到 Top components和Top consumers 差不多,區(qū)別似乎不是很大。

          Component Report 組件的一些報(bào)告(分析屬于公共根包或類(lèi)加載器的對(duì)象)

          Duplicate Classes 用來(lái)查找重復(fù)的類(lèi)

          其中 Component ReportDuplicate Classes 我個(gè)人認(rèn)為不常用,不再過(guò)多介紹。

          在排查分析時(shí)候,我認(rèn)為 「Histogram」 ,「Leak Suspects」,「Dominator Tree」「Top Consumers」,「Top Components」,這些都得好好觀察下,越多觀察,答案就會(huì)離你越近。

          mat觀察到的結(jié)果

          Histogram 結(jié)果:

          a5e865cb0c327579f51e206330ed9d09.webpHistogram

          由于 Histogram 是列出每個(gè)類(lèi)所對(duì)應(yīng)的對(duì)象個(gè)數(shù),以及所占用的內(nèi)存大小,所以一般比較基礎(chǔ)的類(lèi),對(duì)象都比較多,這也是正?,F(xiàn)象,比如(基本類(lèi)型數(shù)組,以及String, map, list 等各種集合以及 Java中的一些自帶的類(lèi)),但是其中一個(gè)值的注意 就是com.mysql,jdbc.ByteArrayRow 這個(gè)類(lèi)很顯眼,看起來(lái)就是邏輯上的一行數(shù)據(jù),這個(gè)類(lèi)的對(duì)象這么多,不禁讓我起疑了,ok , 下邊繼續(xù)看其他維度的分析結(jié)果。

          Dominator Tree 結(jié)果

          可以清楚的看到,其中某個(gè)arrayList占到了 整個(gè)堆的 56.90% 說(shuō)明有大對(duì)象出現(xiàn)了。(list里邊的對(duì)象其實(shí)就是 com.mysql,jdbc.ByteArrayRow !)

          c14c12eab81a381bf1064e57c32f1dce.webpDominator Tree

          Leak Suspects 結(jié)果

          c12dc463d0869cabddd98632de57895d.webpLeak Suspects

          上邊截圖告訴我們可能存在內(nèi)存泄露,于是我追蹤一下,點(diǎn)擊 「outgoing references」 (說(shuō)明:outgoing references 應(yīng)該是可以觀察到這個(gè)線程內(nèi),大概都做了哪些事情,或者可以簡(jiǎn)單粗暴理解為 這個(gè)線程都引用了哪些對(duì)象) ,結(jié)果如下:

          1dc1defbdc40f154827e2193588aced1.webpLeak Suspects 結(jié)果

          ps: 由于 Top ConsumersTop Components 的分析結(jié)果與 Dominator Tree「結(jié)果很像」 我就不貼出來(lái)了。

          定位到問(wèn)題和代碼片段

          Histogram,Dominator Tree,Leak Suspects 三項(xiàng)指標(biāo)分析得出 「本次問(wèn)題的原因」

          「某個(gè)sql查詢(xún)出了幾百萬(wàn)條數(shù)據(jù)(幾百萬(wàn)個(gè)ByteArrayRow對(duì)象),導(dǎo)致list集合占到堆內(nèi)存的56.90%(導(dǎo)致GC出現(xiàn)問(wèn)題)」

          ?

          說(shuō)明:遺憾的是沒(méi)有拿到GC日志,只能從監(jiān)控面板和mat工具觀察:正向(jvm監(jiān)控)+反向(mat得出結(jié)果),來(lái)證實(shí)是GC問(wèn)題,而不能從GC日志直接入手。

          ?

          代碼一覽

          ok,到這里其實(shí)我已經(jīng)根據(jù)mat中的sql:

          9b955cd26d7762f34bf42d80c2dfce62.webp代碼一覽

          找到代碼片段了,代碼如下:

          52134ca76f440ff737a99fc3bc02d2dc.webp

          看到這個(gè)代碼,我思緒萬(wàn)千。。。。。一時(shí)不知如何言語(yǔ)。。。。

          條件是空,不就是select a,b,c from tableA where 1=1 了?這不就是全表掃描了嗎 ,殘酷,無(wú)情。。。

          解決

          解決辦法 so easy 將 1=1 去掉,并且把 if 判斷也去掉,傳進(jìn)來(lái)的條件為null時(shí),拿null去匹配,然后結(jié)果返回的也是空就完事了(因?yàn)樵撟侄问潜厝徊皇强盏模?/p>

          總結(jié)

          1. 首先本次排查過(guò)程,借助兩大工具,一個(gè)就是jvm監(jiān)控也即:Prometheus+ grafana 通過(guò)這倆兄弟的組合,我們可以觀察到j(luò)vm情況,直觀的看出服務(wù)是否有異常。

          2. 第二就是dump堆棧文件,因?yàn)閖vm監(jiān)控面板gc及其不正常,所以順藤摸瓜找到堆棧信息 (這里謝謝運(yùn)維同學(xué)),并通過(guò)mat工具分析,然后找到可疑地方,不得不說(shuō)此次排查還算比較順利,直接找到了問(wèn)題點(diǎn)以及sql語(yǔ)句都找出來(lái)了,這樣更快速的定位了問(wèn)題代碼。

          3. 說(shuō)明:由于本篇文章關(guān)注實(shí)際排查過(guò)程,對(duì)cms gc知識(shí)未做過(guò)多展開(kāi)。另外本次的小遺憾就是沒(méi)有拿到 GC 日志,下次出現(xiàn)問(wèn)題第一時(shí)間要GC日志以及堆棧信息和線程文件 「統(tǒng)統(tǒng)都要」 哈哈~ 。

          4. 「結(jié)論(重要):」 雖然沒(méi)拿到GC日志,但是通過(guò)我個(gè)人的經(jīng)驗(yàn)來(lái)說(shuō),可以基本確定本次告警的原因 即:

            ?

            間接原因:由于全表掃描,返回幾百萬(wàn)數(shù)據(jù)(全部緩存在了內(nèi)存中)

            直接原因:由于內(nèi)存中數(shù)據(jù)過(guò)多,在CMS GC 的Final Remark(重新標(biāo)記階段)這個(gè)耗時(shí)就會(huì)很長(zhǎng)(我猜測(cè)這個(gè)重新標(biāo)記 耗時(shí)正好是監(jiān)控看到的46.6秒,或者比這個(gè)值小點(diǎn)),并且這個(gè)重新標(biāo)記階段是Stop The World,也就是說(shuō)在一段時(shí)間內(nèi)服務(wù)將暫停所有的工作線程,也就導(dǎo)致了服務(wù)吞吐下降,大量接口超時(shí)的現(xiàn)象了~

            ?

          千里之行始于足下,其實(shí)工作久了就會(huì)發(fā)現(xiàn),很多看似很?chē)?yán)重的問(wèn)題,其實(shí)最后排查到的問(wèn)題點(diǎn),都是一個(gè)很基礎(chǔ)的東西,或者說(shuō)一個(gè)很簡(jiǎn)單的東西引起的。就比如這次這個(gè)sql的書(shū)寫(xiě) 真的是很基礎(chǔ)很基礎(chǔ)了,但是就是這么基礎(chǔ)的東西,一不留心就會(huì)全表掃描,小表沒(méi)事,大表的話返回幾百萬(wàn),甚至幾千萬(wàn)幾億的數(shù)據(jù),那接口還不超時(shí)?服務(wù)還不宕機(jī)?所以敬畏每一行代碼,把每一件小事做好,就是我追求的目標(biāo)。

          瀏覽 60
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日批免费视频观看 | 2026国产精品 | 91成人电影 | 国产久久久久 | 天天干天天爱天天爽 |