溫馨提示×

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

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

如何優(yōu)化JVM OOM

發(fā)布時(shí)間:2021-10-20 15:52:19 來(lái)源:億速云 閱讀:140 作者:iii 欄目:編程語(yǔ)言

這篇文章主要講解了“如何優(yōu)化JVM OOM”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何優(yōu)化JVM OOM”吧!

剛接手的服務(wù),正常穩(wěn)定運(yùn)行了很長(zhǎng)一段時(shí)間,在大家伙收拾東西準(zhǔn)備回家過(guò)年時(shí),突然就抽風(fēng)了。

接口失敗率居高不下?

看日志!

GC overhead limit exceeded          

java.lang.OutOfMemoryError:GC overhead limit exceeded          

看一下JVM堆棧

sudo jmap -heap port        

#eg:sudo jmap -heap 9999        

如何優(yōu)化JVM OOM

很明顯,是內(nèi)存不夠了。

我當(dāng)時(shí)的第一想法就是,應(yīng)該是內(nèi)存泄漏!我的思路如下:

1、先入為主,因?yàn)橹疤幚磉^(guò)一次因內(nèi)存泄漏導(dǎo)致的JVM OOM問(wèn)題,所以當(dāng)時(shí)高度懷疑內(nèi)存泄漏。

2、導(dǎo)出JVM堆數(shù)據(jù),分析、定位問(wèn)題。

3、fix bug,重新部署,finish!

我按照這個(gè)思路,分析堆棧后,發(fā)現(xiàn)堆中有大量對(duì)象,這些對(duì)象還沒(méi)來(lái)得及回收,其他線程又在申請(qǐng)內(nèi)存,從而導(dǎo)致了OOM。造成問(wèn)題的直接原因是業(yè)務(wù)請(qǐng)求量增加了,而現(xiàn)有的機(jī)器資源不夠用。至于間接原因,下一篇文章再詳細(xì)描述。

在揭開(kāi)問(wèn)題的謎底后,回過(guò)頭想一想,如果當(dāng)時(shí)能夠仔細(xì)分析一下問(wèn)題,或許問(wèn)題會(huì)被更快解決。

事后反思:服務(wù)已經(jīng)穩(wěn)定正常運(yùn)行了一段時(shí)間,且一個(gè)月內(nèi)未修改代碼和更新服務(wù)。如果是代碼有問(wèn)題,那么問(wèn)題極大可能會(huì)在新代碼上線后的幾天內(nèi)出現(xiàn)?;谶@一點(diǎn),基本可以排除代碼問(wèn)題。

線上服務(wù)出現(xiàn)問(wèn)題,首要的任務(wù)就是盡快恢復(fù)服務(wù)可用。如果下次出現(xiàn)類似問(wèn)題,我會(huì)選擇流程一,而非流程二。

如何優(yōu)化JVM OOM

如何優(yōu)化JVM OOM

造成服務(wù)不可用的直接原因是服務(wù)請(qǐng)求量上升,而根本原因是由于下游服務(wù)負(fù)載過(guò)高,導(dǎo)致微服務(wù)調(diào)用超時(shí),從而引起連鎖反應(yīng)。

下圖呈現(xiàn)了用戶發(fā)起請(qǐng)求到響應(yīng)完成的大致流程。

如何優(yōu)化JVM OOM

業(yè)務(wù)服務(wù)接口和算法服務(wù)接口使用eureka作為服務(wù)注冊(cè)中心,整體來(lái)說(shuō),這個(gè)服務(wù)采用相對(duì)簡(jiǎn)單的微服務(wù)架構(gòu)。

服務(wù)接口搭配feign來(lái)請(qǐng)求算法服務(wù)接口。

 

@FeignClient(value = "image-service")        

public interface ImageService {        

@PostMapping(value = "/XXX")        

String XXX(@RequestParam("img_base64") String imgBase64);        

}        

上面的代碼在執(zhí)行請(qǐng)求的時(shí)候,會(huì)將請(qǐng)求參數(shù)進(jìn)行拼接。

 

image-service/xxx?img_base64=fjsfdgldfgrwdfdmgfdglwefsl        

當(dāng)eureka真正確定請(qǐng)求的服務(wù)地址后,又會(huì)再做一次拼接處理。

 

127.0.0.1:5000/xxx?img_base64=fjsfdgldfgrwdfdmgfdglwefsl        

算法服務(wù)接口的處理時(shí)間與圖片的大小正相關(guān),圖片越大,處理時(shí)間越長(zhǎng)。由于處理圖片是一個(gè)相對(duì)耗時(shí)的操作,接口會(huì)出現(xiàn)超時(shí)的情況。如果請(qǐng)求失?。ǔ瑫r(shí)),那么feign會(huì)進(jìn)行重試。

圖片base64字符串的長(zhǎng)度與圖片大小呈正相關(guān)關(guān)系,圖片越大,base64字符串長(zhǎng)度越長(zhǎng)。一張306K的圖片,轉(zhuǎn)成base64格式后,字符串長(zhǎng)度為429196。

如何優(yōu)化JVM OOM

因此處理一次正常的請(qǐng)求消耗的內(nèi)存比較大。圖片越大,算法處理時(shí)間越久,超時(shí)失敗后,feign重試,重試之后又失敗,導(dǎo)致一個(gè)惡性循環(huán)(幸好有超時(shí)次數(shù)限制,否則如此遞歸下去,后果不堪設(shè)想)。

如圖是JVM OOM后拿到堆棧的數(shù)據(jù),最大的圖片base64的大小有5M。

如何優(yōu)化JVM OOM

jdk1.8 JVM參數(shù)PretenureSizeThreshold的默認(rèn)值是2M。

如何優(yōu)化JVM OOM

當(dāng)base64字符串超過(guò)2M時(shí),會(huì)直接分配到老年代,這無(wú)疑加大了JVM老年代的內(nèi)存壓力,導(dǎo)致頻繁Full GC。

如何優(yōu)化JVM OOM

為何使用image base64傳輸圖片?

1、歷史原因。

2、開(kāi)發(fā)相對(duì)簡(jiǎn)單。

該如何優(yōu)化?

1、提高feign請(qǐng)求的超時(shí)時(shí)間。

2、提高機(jī)器配置。

3、將image base64放到請(qǐng)求體中,減少因feign框架對(duì)參數(shù)進(jìn)行拼接帶來(lái)的內(nèi)存開(kāi)銷。

感謝各位的閱讀,以上就是“如何優(yōu)化JVM OOM”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)如何優(yōu)化JVM OOM這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向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