溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦

發(fā)布時(shí)間:2022-01-04 09:37:14 來(lái)源:億速云 閱讀:398 作者:小新 欄目:大數(shù)據(jù)

這篇文章主要介紹java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

介紹

業(yè)務(wù)部門的一個(gè)同事遇到個(gè)奇怪的 Full GC 問(wèn)題,有個(gè)服務(wù)遷移到新的應(yīng)用后,一直頻繁 Full GC。新應(yīng)用機(jī)器的配置是 4c 8g,老應(yīng)用是 4c 4g,老應(yīng)用 GC 都很正常,并且代碼沒(méi)有變更,所以比較奇怪。

現(xiàn)象

問(wèn)題的現(xiàn)象是,從監(jiān)控圖上看一直有大量的 Full GCjava中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦

排查

遇到這個(gè)問(wèn)題,一般都是先看看各個(gè)區(qū)的內(nèi)存占用情況:java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦

從監(jiān)控圖上看 Old Gen、Young Gen、Perm Gen,沒(méi)什么問(wèn)題,不會(huì)觸發(fā) Full GC,當(dāng)然這里看各個(gè) Gen 是否會(huì)觸發(fā) Full GC 需要結(jié)合 JVM 參數(shù)配置來(lái)看。

順便也看了下 GC 日志,一直狂暴 CMS GC 日志,而且可以看到老年代使用空間也不大,細(xì)心可以發(fā)現(xiàn),大量的 CMS GC 中夾雜著 Young、Perm 區(qū)的回收,所以其實(shí)是 Full GC。GC 日志如下:java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦

老應(yīng)用的 JVM 參數(shù)配置java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦

新應(yīng)用的 JVM 參數(shù)配置java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦

通過(guò)上面的觀察,再根據(jù)一般觸發(fā) CMS GC 幾個(gè)可能性:

  • Old Gen 使用達(dá)到一定的比率,默認(rèn)為92%,這里看 CMSInitiatingOccupancyFraction=80%,而實(shí)際才使用 2%(看監(jiān)控圖表)不到,所以排除這種情況。

  • 配置了 CMSClassUnloadingEnabled,且 Perm Gen 的使用達(dá)到一定的比率默認(rèn)為 92%,這里看 CMSInitiatingPermOccupancyFraction=80%,而實(shí)際才使用 30%(看監(jiān)控圖表)不到,所以排除這種情況。

  • 配置了 ExplictGCInvokesConcurrent 且未配置 DisableExplicitGC 的情況下顯示調(diào)用了 System.gc()。

  • Hotspot 自己根據(jù)估計(jì)決定是否要觸法,如 CMS 悲觀策略,這類可以通過(guò) GC 日志分析。

大致判斷很可能是 System.gc() 導(dǎo)致的問(wèn)題,但是怎么定位調(diào)用 System.gc() 的代碼呢? 當(dāng)時(shí)就想如果是 System.gc() 引起的頻繁 Full GC,jstack 線程堆棧應(yīng)該能看到一些信息,果不其然,確實(shí)通過(guò)線程堆棧找到了。java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦

jstack 作用非常大,很多問(wèn)題都能從這里發(fā)現(xiàn),而且比較輕量,對(duì)應(yīng)用基本無(wú)影響。某次的 jstack 信息只代表那個(gè)時(shí)刻的線程堆棧,有時(shí)只看一個(gè) jstack 信息可能看不出什么問(wèn)題,一般可以多 jstack 幾次,然后對(duì)比去看,基本就能發(fā)現(xiàn)一些問(wèn)題。 (當(dāng)然該問(wèn)題,也可能不是頻繁的 Full GC,可能通過(guò) jstack 定位不到問(wèn)題,可以 jstat -gccause pid 1000,來(lái)查看 gc 原因。)

很明顯,是由于 jxl 這個(gè)包中的 close 方法顯示調(diào)用了 System.gc() 導(dǎo)致的問(wèn)題。

跟了下代碼,自然確實(shí)存在這段代碼,不過(guò)有個(gè)設(shè)置開(kāi)關(guān),可以 disable 這個(gè)功能,所以在使用的時(shí)候可以設(shè)置 setGCDisabled(true),關(guān)閉觸發(fā) System.gc()。java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦

但是為什么老應(yīng)用沒(méi)有問(wèn)題呢,主要是因?yàn)樗?-XX:+DisableExplicitGC,屏蔽了 System.gc() 動(dòng)作,新應(yīng)用的 JVM 沒(méi)有這個(gè)配置。

可能大家還有個(gè)疑問(wèn),都知道 System.gc() 會(huì)觸發(fā) Full GC,那為什么一直進(jìn)行 CMS GC(通過(guò)GC日志)呢? 主要是因?yàn)檫@個(gè)參數(shù) -XX:+ExplicitGCInvokesConcurrent,打開(kāi)此參數(shù)后,會(huì)做并行 Full GC,只有配置 -XX:+UseConcMarkSweepGC 這個(gè)參數(shù),該參數(shù)才會(huì)生效。因此,System.gc() 時(shí) Old 區(qū)會(huì)進(jìn)行 CMS GC,可提高 Full GC 效率。

以上是“java中依賴包濫用System.gc()導(dǎo)致的頻繁Full GC怎么辦”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI