能定位到是JVM老年代內(nèi)存飆高,說(shuō)明題主對(duì)JVM有了一定認(rèn)識(shí)并且可能對(duì)JVM分代回收機(jī)制也有了解。
因?yàn)槔夏甏鷥?nèi)存存儲(chǔ)對(duì)象是新生代中通過(guò)多次mingc都沒(méi)有被釋放掉的對(duì)象(或者age達(dá)到一定值或者新生代內(nèi)存告急,導(dǎo)致頻繁mingc,GC的同時(shí)引發(fā)majGC)
我就簡(jiǎn)單說(shuō)一下在什么情況下可能產(chǎn)生老年代內(nèi)存突然飆高以及其原因:
可能原因
- 死循環(huán)中不斷創(chuàng)建對(duì)象,導(dǎo)致Eden區(qū)內(nèi)存爆滿引起mingc,同時(shí)因?yàn)橐廊淮嬖谝?新生代內(nèi)存空間不足引起頻繁mingc進(jìn)而age快速增大然后被放入老年代中,使得老年代內(nèi)存飆升。當(dāng)然飆升一次最多也就是新生代的內(nèi)存也就是1/3。
- 載入大批量對(duì)象。這個(gè)大概率是從DB中獲取數(shù)據(jù)時(shí)未限制返回條數(shù)或者返回條數(shù)設(shè)置失效導(dǎo)致一個(gè)查詢(xún)導(dǎo)致內(nèi)存暴增,引起連鎖反應(yīng)如上。
- 業(yè)務(wù)邏輯新增眾多靜態(tài)引用對(duì)象或者類(lèi)引用(這個(gè)往往是外行或者新手或者一些理論還不錯(cuò)的坑爹領(lǐng)導(dǎo)寫(xiě)的代碼)。
- JVM分代內(nèi)存大小比例設(shè)置和當(dāng)前業(yè)務(wù)需求不匹配,可能項(xiàng)目業(yè)務(wù)需求已啟動(dòng)就需要50M內(nèi)存空間而你只為新生代設(shè)置了60M內(nèi)存空間。
解決方式
通過(guò)linuxtop和jmap-histo:live[pid]命令快速定位大內(nèi)存代碼塊。不清楚的可以百度或者私信,手把手教會(huì)。
合理分配JVM堆內(nèi)存分代比例??梢酝ㄟ^(guò)簡(jiǎn)單計(jì)算獲取服務(wù)器啟動(dòng)所需內(nèi)存,再通過(guò)一定比例設(shè)置。這個(gè)比例大致相同但是也可能根據(jù)項(xiàng)目特色發(fā)生比較大的變化。比如老年代:新生代=2:1,Eden:A:B=8:1:1。這些都是可以調(diào)整的。