這篇文章給大家分享的是有關(guān)full gc查找問(wèn)題的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
為企業(yè)提供成都網(wǎng)站建設(shè)、做網(wǎng)站、網(wǎng)站優(yōu)化、成都營(yíng)銷網(wǎng)站建設(shè)、競(jìng)價(jià)托管、品牌運(yùn)營(yíng)等營(yíng)銷獲客服務(wù)。創(chuàng)新互聯(lián)公司擁有網(wǎng)絡(luò)營(yíng)銷運(yùn)營(yíng)團(tuán)隊(duì),以豐富的互聯(lián)網(wǎng)營(yíng)銷經(jīng)驗(yàn)助力企業(yè)精準(zhǔn)獲客,真正落地解決中小企業(yè)營(yíng)銷獲客難題,做到“讓獲客更簡(jiǎn)單”。自創(chuàng)立至今,成功用技術(shù)實(shí)力解決了企業(yè)“網(wǎng)站建設(shè)、網(wǎng)絡(luò)品牌塑造、網(wǎng)絡(luò)營(yíng)銷”三大難題,同時(shí)降低了營(yíng)銷成本,提高了有效客戶轉(zhuǎn)化率,獲得了眾多企業(yè)客戶的高度認(rèn)可!
背景
一個(gè)服務(wù)突然所有機(jī)器開(kāi)始頻繁full gc。而服務(wù)本身沒(méi)有任何改動(dòng)和發(fā)布記錄。上線查看gc log日志,日志如下:
從日志來(lái)看,每次發(fā)生full gc的時(shí)候都比較奇怪,主要有兩點(diǎn),第一、old區(qū)域和perm的區(qū)域使用率很低,沒(méi)有到達(dá)觸發(fā)full gc的條件,第二、項(xiàng)目中配置的是CMS,為什么沒(méi)有進(jìn)行 CMS GC,直接進(jìn)行了full gc呢。
查找過(guò)程
第一、代碼會(huì)不會(huì)是調(diào)用了System.gc()
考慮在使用direct memory的時(shí)候,先判斷direct memory是否足夠,要是不足的話會(huì)使用System.gc()嘗試釋放內(nèi)存。于是直接使用反射去監(jiān)控direct memory。發(fā)現(xiàn)direct memory的使用率始終在10%左右,不可能去調(diào)用System.gc()。
而且此時(shí)去查看jvm參數(shù)已經(jīng)禁止顯示調(diào)用了System.gc()了。
第二、使用 jstat -gccause查看gc原因
想著要是能找到gc的原因就好了。于是使用 jstat -gccause實(shí)時(shí)監(jiān)控gc原因,但是發(fā)現(xiàn)始終是Allocation Failure。但是在監(jiān)控中發(fā)現(xiàn)old區(qū)域中有突然增加800M,通過(guò)我司的監(jiān)控平臺(tái)也發(fā)現(xiàn)了old區(qū)域暴漲的現(xiàn)象。監(jiān)控如下:
并且通過(guò)jmap -histo pid查看old Gen 突變前后內(nèi)存增加值,發(fā)現(xiàn)增加的800M全部是byte[],并且dump內(nèi)存下來(lái)使用MAT查看內(nèi)存,然后并沒(méi)有什么收獲。
第三、找到有問(wèn)題開(kāi)始時(shí)候的改動(dòng)點(diǎn)
因?yàn)轫?xiàng)目在發(fā)生問(wèn)題的時(shí)候并沒(méi)有改動(dòng)和上線,基本上就排除代碼本身的原因。聯(lián)系運(yùn)維告知那個(gè)時(shí)間點(diǎn),我們所在的服務(wù)節(jié)點(diǎn)上部署了log_agent。
log_agent的作用就是把本地日志上報(bào)到日志中心存儲(chǔ)起來(lái),其架構(gòu)示意圖demo如下:
猜著肯定是和log_agent通信的時(shí)候有bug導(dǎo)致的,于是讓運(yùn)維幫忙把其中一臺(tái)機(jī)器上的log_agent給刪除了,刪除之后full gc恢復(fù)正常。
到此基本上確定了是日志上報(bào)導(dǎo)致的問(wèn)題。
第四、定位日志上報(bào)的jar具體有問(wèn)題的代碼
定位到是日志上報(bào)的jar導(dǎo)致的問(wèn)題之后,就把這個(gè)問(wèn)題反饋給了相關(guān)負(fù)責(zé)人。但是他們追蹤了很久之后并沒(méi)有發(fā)現(xiàn)什么問(wèn)題。
之后有時(shí)間之后,我就把他們相關(guān)代碼看了一下,發(fā)現(xiàn)其中有段代碼有點(diǎn)問(wèn)題。有問(wèn)題代碼如下:
在出入log的的時(shí)候在append中會(huì)調(diào)用sendLogEntry這個(gè)方法,而logEntries本身是個(gè)list對(duì)象,非線程安全的。這樣的話,在多個(gè)線程中同時(shí)輸出日志就有安全問(wèn)題。于是就在sendLogEntry這個(gè)方法上加上線程安全(synchronized),上線問(wèn)題解決,沒(méi)有發(fā)生頻繁full gc了。
但是多線程下同時(shí)調(diào)用list也不應(yīng)該頻繁full gc啊,這個(gè)地方有bug,但是不應(yīng)該導(dǎo)致頻繁 full gc。我懷疑是client.Log(logEntries); 這個(gè)方法本身不是線程安全的。以為我把線程同步塊鎖在了client.Log(logEntries);這個(gè)代碼塊上。發(fā)現(xiàn)問(wèn)題也得以解決。
client.Log的代碼就是一個(gè)發(fā)送相關(guān)日志、并接收返回值進(jìn)行確認(rèn),使用的是thrift框架進(jìn)行通信的。于是在接收返回值的地方,給加了點(diǎn)log。代碼如下:
從日志中我們可以看到,從返回值中讀取的字節(jié)流大小最大達(dá)1.2G甚至1.8G,這很明顯不正常啊。因?yàn)閥oung Gen 1.5G,old Gen 1G,必定會(huì)拋OOM。而在最上層捕獲了error,但是默認(rèn)情況下卻沒(méi)有l(wèi)og,導(dǎo)致log中看不出任何問(wèn)題。
回想起我司RPC服務(wù)也是用的thrift是用的連接池的方式,所以client肯定是非線程安全的。
問(wèn)題定位到之后,準(zhǔn)備反饋給那個(gè)人。發(fā)現(xiàn)那個(gè)人已經(jīng)離職了。于是嘗試升級(jí)到最新的jar之后,發(fā)現(xiàn)他們?cè)趕endLogEntry這個(gè)方法上加上了synchronized。
總結(jié)
上面給出了總結(jié)后應(yīng)該遵循的定位問(wèn)題步驟。真實(shí)的查找過(guò)程絕不是按照上面的那個(gè)過(guò)程來(lái)的,這個(gè)問(wèn)題的追查持續(xù)了大概兩周(每天投入1-2個(gè)小時(shí)左右吧?)。
主要有兩個(gè)坑:
gc log。開(kāi)始的時(shí)候關(guān)注點(diǎn)一直在gc log上。從gc log來(lái)看根本不滿足發(fā)生full gc的條件。于是專注點(diǎn)在認(rèn)為引入的jar有在調(diào)System.gc()并沒(méi)有注意到這個(gè)-XX:+DisableExplicitGC參數(shù)
對(duì)Error的處理。我司日志中心提供的jar居然直接忽略了Error導(dǎo)致了OOM日志一直沒(méi)有顯示出來(lái),不然問(wèn)題發(fā)生時(shí)肯定就能直接定位到了。
JVM拋出OOM之后,就算配置的是CMS,JVM仍舊是使用的Full GC來(lái)回收內(nèi)存。因?yàn)镃MS會(huì)有內(nèi)存碎片化問(wèn)題,已經(jīng)發(fā)生了OOM,可能是因?yàn)闆](méi)有連續(xù)內(nèi)存存放新申請(qǐng)的對(duì)象,F(xiàn)ull GC沒(méi)有內(nèi)存碎片的問(wèn)題,所以直接使用Full GC回收的策略是合理的。
感謝各位的閱讀!關(guān)于“full gc查找問(wèn)題的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
當(dāng)前題目:fullgc查找問(wèn)題的示例分析
網(wǎng)站網(wǎng)址:http://chinadenli.net/article32/gioipc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、ChatGPT、企業(yè)網(wǎng)站制作、外貿(mào)建站、用戶體驗(yàn)、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)