JVM調優之服務內存超過閾值報警

今早收到一條短信,具體報警信息如下:

【UMP JVM監控內存報警】應用名:發券worker(jdos_couponwkr);KEY【coupon.send.worker.jvm】,主機名:【host-10-183-72-114】,實例【11909223645】的堆內存使用率連續3次超過設定閥值【90.0%】。報警級別:【Warning】,報警時間:【2019-07-17 07:36:12】。

說是有一臺機器的堆內存使用超過閾值90%。這條短信雖然言簡意賅,但是背後隱藏的技術細節,我這裏來陳述一下,謬誤之處,還請指教。

初看此報警,則知道堆內存使用超過閾值了。第一反應一般都是把堆內內存調大,就行了。但是事實真的如此嗎?不妨來一起看看。

假設我們現在堆內內存爲1G,則堆內存使用曲線如下:

image

可以看到整體使用正常,回收正常,非常平穩。

現在,我們把堆內內存調整爲2G,則堆內內存使用曲線如下:

image

可以看到,堆內內存使用率依然超過90%,說明單純的調節堆內內存的大小,是無法解決此問題的。

爲什麼呢? 由於jvm工作的時候,對堆內內存的使用是自適應的,你給的多,它用的多,你給的少,它用的少。所以這也是爲啥你給它1G大小,它能將堆內存用的超過90%,你給他2G大小,他也能將堆內存用的超過90%。當然,前提是應用的內存使用量大於2G才行。否則分配給2G的堆內存,則不會使用這麼高。可能用到1.5G左右就釋放了。

 

再來說說垃圾回收機制。這裏我將G1算法之外的統稱爲老算法。咱們來比較一下:

在8G堆內存的docker上,同一個應用,同一業務,壓測結果如下:

1. young gc次數,老算法20次,G1算法8次。

2. 堆內存使用最大值,老算法使用最大6.3G,G1算法使用最大7.6G。

可以看出,在8G堆內存的場景下,G1算法整體表現優異,更少的gc次數,更高效率的堆內存使用率。

但是在8G以下堆內存使用的場景中,G1算法則優勢並不明顯。所以強烈建議堆內存比較大的應用開啓G1算法。

 

最後說下,遇到此短信提示需要檢查的內容。

1. 檢查yong gc耗時,平均耗時40ms以內正常,超過1s則需要排查問題。

2. 檢查full gc次數,一分鐘內數次或者數十次則顯得頻繁,需要排查。

3. 檢查堆內存回收圖形,如果內存使用率上去了,但是遲遲下不來,則意味着老年代無法回收,檢查代碼查明原因,類似圖形如下:

image

可以看到此圖中,曲線上去後下不來,原因是應用內部有個本地cache一直在運行且無過期機制導致,後來關閉掉此本地cache則回收正常。

4. 根據jvm使用率曲線的最高點來看當前堆內存大小是否符合設置,如果當前堆內存使用率頂點一直較高,則應用需要的內存比分配的堆內存要大一些,可以在內存資源足夠的情況下嘗試多分配一些堆內存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章