先說結論:通過優化Xms,改為和Xmx一致,使系統的超時率降了四分之三
1. 背景
一個同事說他負責的服務在一次上線之后超時率增加了一倍
2. 分析
2.1 機器的監控
首先找了一臺機器,看了監控
上線后最明顯的變化就是CPU使用率變高了
2.2 上線改動點
上線只加了簡單的判斷條件,按理不應該導致CPU變高成這樣
2.3 CPU使用率隨時間變低
又發現了一個奇怪的現象是,在沒有上線的情況下,CPU使用率突然降低了,然后就一直保持著很低的狀態
CPU降低之后,超時率也有所降低,現在大概能理解超時是和CPU使用率有關的,可能存在CPU瓶頸
2.4 依賴的服務
既然在沒有上線的情況下,CPU使用率會降低,肯定有什么因素影響,猜測可能是依賴的服務,但依賴的服務太多,也沒辦法一個一個去看,哪個呼叫有問題
2.5 CPU和上線的關系
于是還是想在CPU使用率上找找問題,因為是上線導致的CPU使用率變高,所以看了其他上線時間的CPU使用率
還是有點思路了,發現大部分上線之后CPU使用率是會變高,部分沒有(后面知道,因為有的上線本身就是優化,所以CPU使用率也會變低)
2.6 CPU和記憶體的關系
之前一直在關心CPU,突然看見了記憶體的使用率,一下就明白的問題所在,從下面這張圖可以看出,CPU使用率和記憶體使用率是成反比的
使用Java的都應該清楚,記憶體不夠的時候,就會STW,然后去啟動GC執行緒去GC,而且一般情況GC執行緒數和CPU核數是一致的,這個服務也是如此,此時CPU使用率必然是會變高的
上面3月6號CPU突然下降的原因也是因為記憶體使用變高了,這是在沒有上線的情況下
2.7 記憶體和JVM引數
可以看到上面的圖中,CPU使用率高的時候,記憶體占用只有20%左右,為什么空這這么多記憶體不用呢?看下JVM引數
-Xmx16g -Xms4g -Xss1024K -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=10 -XX:MetaspaceSize=512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=8 -XX:ConcGCThreads=8 -XX:G1HeapRegionSize=16m -XX:-OmitStackTraceInFastThrow
Xms配的是4G,也就是說JVM在啟動時只會申請4G記憶體,當記憶體不足時,先會GC,當GC釋放的記憶體還不夠時,才會去申請更大的記憶體
這樣的策略一般是為了節省記憶體,但目前主流的都是容器,節省下來的記憶體也不會給別的服務利用,所以我們這可以直接把Xms改為16G
改完之后立即得到了很好的效果,超時率降了四分之三,不過后續因為記憶體使用率變高,超過了閾值,所以又把Xmx和Xms調整為14G,這個問題可以參考我之前的文章一次Java服務記憶體過高的分析程序
3. 總結
- Xms配置過小,JVM啟動時記憶體不足導致GC執行緒占用過多CPU
- CPU不足時,超時率增加,CPU充足時,超時率降低
- Xms配置和Xmx一樣,超時率降低
4. Xms和Xmx
這兩個引數使用Java的都比較了解
Xmx: JVM的最大堆記憶體
Xms: JVM的初始堆記憶體
4.2 不一致的壞處
- 堆記憶體不夠時更頻繁的觸發GC
- 當GC完之后記憶體也不夠時,向系統申請記憶體,會花費更多的時間
4.2 改為一致的好處
為了避免在生產環境由于heap記憶體擴大或縮小導致應用停頓,降低延遲,同時避免每次垃圾回收完成后JVM重新分配記憶體,所以,-Xmx和-Xms一般都是設定相等的
在生產環境中把Xms和Xmx設為相同值也是Oracle官方推薦
5. 感想
這個配置從機器上線跑了兩年一直如此,大部分時間性能沒被充分利用,現在有二十臺機器都是以這樣一種低性能模式跑了這么久,這絕對是一種浪費
在第三篇參考文章中,有個人的評論正好和我相反,他認為一開始將Xms和Xmx設定為一樣,而實際沒用那么多,其實也是一種浪費,不過這是18年前的文章,那時容器沒有興起,服務都在一個物理機上面共享記憶體,會是有這種問題的
在容器中,節省的記憶體別的服務也利用不了,所以Xms最后設定和Xmx一致,但是容器也是可能造成浪費的,比如上面我把Xmx和Xms從16G改為14G,從監控上來看耗時和超時率下降了一點,也就是把這個容器的記憶體往下調一點也是可以接受的,具體調到多少合適也不太確定
不過這種優化很沒有必要,記憶體是很便宜的,而且適量冗余一些性能也可以理解
既然這么多好處,為什么Oracle不默認把Xms和Xmx設定為一致呢,我覺得可能是目前還是有大部分Java應用都不是容器環境,全域考慮,沒有這樣做,或許后續Java會判斷是否是容器環境來自動設定Xms
參考
[1] JVM的Xms和Xmx引數設定為相同值有什么好處?
[2] Is there any advantage in setting Xms and Xmx to the same value?
[3] large difference between -Xms and -Xmx values in jvm
本文來自博客園,作者:songtianer,轉載請注明原文鏈接:https://www.cnblogs.com/songjiyang/p/17512319.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/556203.html
標籤:Java
上一篇:LRU 快取淘汰演算法
下一篇:返回列表