能定位到是JVM老年代記憶體飆高,說明題主對JVM有了一定認識並且可能對JVM分代回收機制也有了解。
因為老年代記憶體儲存物件是新生代中透過多次mingc都沒有被釋放掉的物件(或者age達到一定值或者新生代記憶體告急,導致頻繁mingc,GC的同時引發majGC)
我就簡單說一下在什麼情況下可能產生老年代記憶體突然飆高以及其原因:
透過linux top和jmap -histo:live [pid] 命令快速定位大記憶體程式碼塊。不清楚的可以百度或者私信,手把手教會。
合理分配JVM堆記憶體分代比例。可以透過簡單計算獲取伺服器啟動所需記憶體,再透過一定比例設定。這個比例大致相同但是也可能根據專案特色發生比較大的變化。比如老年代:新生代=2:1,Eden:A:B=8:1:1。這些都是可以調整的。
能定位到是JVM老年代記憶體飆高,說明題主對JVM有了一定認識並且可能對JVM分代回收機制也有了解。
因為老年代記憶體儲存物件是新生代中透過多次mingc都沒有被釋放掉的物件(或者age達到一定值或者新生代記憶體告急,導致頻繁mingc,GC的同時引發majGC)
我就簡單說一下在什麼情況下可能產生老年代記憶體突然飆高以及其原因:
可能原因死迴圈中不斷建立物件,導致Eden區記憶體爆滿引起mingc,同時因為依然存在引用+新生代記憶體空間不足引起頻繁mingc進而age快速增大然後被放入老年代中,使得老年代記憶體飆升。當然飆升一次最多也就是新生代的記憶體也就是1/3。載入大批次物件。這個大機率是從DB中獲取資料時未限制返回條數或者返回條數設定失效導致一個查詢導致記憶體暴增,引起連鎖反應如上。業務邏輯新增眾多靜態引用物件或者類引用(這個往往是外行或者新手或者一些理論還不錯的坑爹領導寫的程式碼)。JVM分代記憶體大小比例設定和當前業務需求不匹配,可能專案業務需求已啟動就需要50M記憶體空間而你只為新生代設定了60M記憶體空間。解決方式透過linux top和jmap -histo:live [pid] 命令快速定位大記憶體程式碼塊。不清楚的可以百度或者私信,手把手教會。
合理分配JVM堆記憶體分代比例。可以透過簡單計算獲取伺服器啟動所需記憶體,再透過一定比例設定。這個比例大致相同但是也可能根據專案特色發生比較大的變化。比如老年代:新生代=2:1,Eden:A:B=8:1:1。這些都是可以調整的。