記一次有驚無險的 JVM 優化經歷

2021-09-25 03:36:35 字數 3059 閱讀 7604

背景

生產環境有二台阿里雲伺服器,均為同一時期購買的,cpu、記憶體、硬碟等配置相同。具體配置如下:

由於這二伺服器硬體和軟體配置相同,並且執行相同的程式,所以在nginx輪詢策略均weight=1,即平台的某個流量由這二台機器平分。

有一次對系統進行例行檢查,使用pinpoint檢視下伺服器」heap usage」的使用情況時,發現在有乙個系統full gc非常頻繁,大約五分鐘一次full gc,嚇我一跳。

這麼頻繁的full gc,導致系統暫停處理業務,對系統的實時可用性大打折扣。

我檢查了一下tomcat(tomcat8.5.28)配置,發現在tomcat沒有作任何關於jvm記憶體的設定,全部使用預設模式。

由於這二伺服器硬體和軟體配置相同,並且執行相同的程式,所以在nginx輪詢策略均weight=1,即平台的某個流量由這二台機器平分。

gc資料

在業務峰期間,通過pinpoint觀察的a、b節點的」heap usage」使用情況,分別進行以下幾個時間段資料。

3小時圖:

上圖b系統在三個小時內,一共發生了22次full gc,大約每8分鐘進行一次full gc。

每次full gc的時間大概有150ms左右,即b系統在三個小時內,大約有3300ms暫停系統執行。

從上圖來看,堆的空間最大值在890m左右,但在堆空間的大小大約200m就發生full gc了,從系統資源的利用角度來考慮,這個使用率太低了。

上圖a系統在3個小時內,一共發生了0次full gc,嗯,就是沒有任何停頓。

在這3小時,系統一直在處理業務,沒有停頓。堆的總空間大約1536m,目前堆的空間大於500m。

6小時圖:

上圖b系統在6個小時的資料統計和3個小時很像,6個小時內一共發生了n次full gc,均是堆的空間小於200m就發生full gc了。

上圖a系統在6個小時內,一共發生了0次full gc,表現優秀。

12小時

上圖b系統在12個小時內,一共發生了n次full gc,左邊full gc比較少,是因為我們的業務主要集中白天,雖然晚上屬於非業務高峰期間,還是有full gc。

上圖a系統在12個小時內,一共發生了0次full gc,表現優秀。

gc日誌

看下gc.log檔案,因為我們兩台伺服器都輸出了gc的詳細日誌,先看下b系統的full gc日誌。

上圖全部是」 [full gc (ergonomics)」日誌,是因為已經去掉」 gc (allocation failure」日誌,這樣更方便觀察和分析日誌。

我們選取gc日誌檔案最後一條full gc日誌。

2018-12-24t15:52:11.402+0800: 447817.937: [full gc (ergonomics) [psyounggen: 480k->0k(20992k)] [paroldgen: 89513k->69918k(89600k)] 89993k->69918k(110592k), [metaspace: 50147k->50147k(1095680k)], 0.1519366 secs] [times: user=0.21 sys=0.00, real=0.15 secs]

可以計算得到以下資訊:

分析:這次full gc是因為老年代物件占用的空間的大小已經超過老年代容量 引發的full gc。

[paroldgen: 89513k->69918k(89600k)]

究其原因,是因為分配給老年代的空間太小,遠遠不能滿足系統對業務的需要。

這導致老年代的空間常常被佔滿,老年代的空間滿了,導致full gc。而由於老年代的空間比較小,所以每次full gc的時間也比較短。

a系統日誌,只有2次full gc,這2次gc均發生在系統啟動時:

7.765: [full gc (metadata gc threshold) [psyounggen: 18010k->0k(458752k)] [paroldgen: 15142k->25311k(1048576k)] 33153k->25311k(1507328k), [metaspace: 34084k->34084k(1081344k)], 0.0843090 secs] [times: user=0.14 sys=0.00, real=0.08 secs]

可以得到以下資訊:

分析:a系統只有系統啟動才出現二次full gc現象,而且是」 metadata gc threshold」引起的,而不是堆空間引起的full gc。

雖然經過乙個星期的觀察,a系統沒有full gc,但一旦發生full gc時間則會比較長。

其它系統曾經發現過,1024m的老年代,full gc持續的時間大約是90ms秒。

所以看得出來推也不是越大越好,或者說在useparalleloldgc收集器中,堆的空間不是越大越好。

分析與優化

總體分析:

優化策略:

一次有驚無險的刪庫經歷

來公司三個月了,資料庫每天都在練習,這幾天我的主管回家了,正好趕上這幾天開新伺服器,我作為乙個剛入門的小白,在一台伺服器上跑起了開服指令碼,由於指令碼上已經寫好了開服的全部指令,我也沒仔細想太多,就將資料庫做了個備份,然後跑起了指令碼當然這個指令碼不是我寫的,跑到一半的時候指令碼突然報錯,我去檢視了...

記一次面試經歷

今早七點半的巴士從中山趕到廣州面試php開發助理,以前面的都是十來人 幾十人的小公司,不少還是培訓公司,坑的一逼!這次的公司不錯,比較正規,好歹上百人了,只是筆試題做得一般,題目有的雖有學過,但忘了,好吧!這就是沒準備充分的緣故!下面羅列下我還記得的題目 有些漏了就沒辦法了 之後hr面試聊了下,雖然...

記一次重構經歷

起因 最近因為公司內部對各個業務線的使用者業務進行統一剝離,形成使用者中心,所有使用者相關的業務和資料都落地到使用者中心,各個業務線以rpc的的形式依賴使用者中心的服務。結果 因為我的疏忽,造成了兩個bug沒有被測試出來。總結改進 這兩個bug的產生的原因都是因為我錯誤地估計了回歸測試的範圍,我的想...