背景
近期線上web服務(wù)內(nèi)存占用較大愉镰,空間資源消耗很多【冢考慮到后續(xù)訪問壓力會越來越大丈探,防止GC頻繁,OOM等內(nèi)存問題爆發(fā)拔莱,提前分析內(nèi)存使用情況碗降。
思路
思路1:重點對象進(jìn)行評估隘竭,預(yù)估其真實大小值,內(nèi)存可占大小遗锣。--探路
思路2:全局觀察數(shù)據(jù),分析堆中對象的大小嗤形,數(shù)目精偿。--全局思考
思路3:結(jié)合思路1,思路2赋兵,理清業(yè)務(wù)邏輯笔咽,推斷內(nèi)存過大原因。--分析總結(jié)
步驟
1霹期,探路
系統(tǒng)主要對外提供數(shù)據(jù)訪問服務(wù)叶组。數(shù)據(jù)的讀取,計算和封裝等操作历造,經(jīng)驗來說就是內(nèi)存占用的最大“元兄”甩十。
簡單的計算數(shù)據(jù)對象大小的方法:對象序列化操作,計算值和真實值的比值約在0.5到2之間吭产。
核心代碼:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(movie.toRecResultVideo().toJSON().toString());
byte[] bs = baos.toByteArray();
m_bytes+=bs.length;
oos.close();
數(shù)量預(yù)估:
使用:jmap -histo $PID | head -n 對象關(guān)鍵字符串
獲得線索對象總量侣监,此時的內(nèi)存大小僅供參考,它依賴的對象是不會計算在內(nèi)的臣淤,不準(zhǔn)確橄霉。
結(jié)合實際業(yè)務(wù)場景,預(yù)估核心數(shù)據(jù)占內(nèi)存的使用大小邑蒋。
2姓蜂,全局思考
jmap是個不錯的jdk自帶的實時java進(jìn)程內(nèi)存分析工具。
使用:jmap -histo $PID | head -n 20
前20條最大內(nèi)存使用對象医吊。
參考數(shù)據(jù):
num? ? #instances? ? ? ? #bytes? class name
----------------------------------------------
1:? ? ? 23576457? ? ? 977320576? [C
2:? ? ? 22579841? ? ? 541916184? java.lang.String
3:? ? ? 7314642? ? ? 234068544? java.util.HashMap$Node
4:? ? ? 1700093? ? ? 132600320? [Ljava.util.HashMap$Node;
5:? ? ? ? 329053? ? ? 122648832? [B
6:? ? ? 1741893? ? ? 83610864? java.util.HashMap
7:? ? ? ? 40426? ? ? 65754792? [Ljava.lang.String;
8:? ? ? ? 818186? ? ? 41559272? [Ljava.lang.Object;
9:? ? ? ? 793279? ? ? 31731160? java.util.HashMap$KeyIterator
10:? ? ? 1489661? ? ? 23834576? org.json.JSONObject
11:? ? ? ? 811144? ? ? 19467456? java.util.ArrayList
12:? ? ? ? 281120? ? ? 17991680? java.net.URL
13:? ? ? ? 49129? ? ? 17498424? [I
14:? ? ? ? 574117? ? ? 13778808? java.lang.StringBuffer
15:? ? ? ? 213742? ? ? 10259616? com.firedata.brain.er.dict.DictElement
16:? ? ? ? 406102? ? ? ? 9746448? com.firedata.brain.er.util.PrefixTrie$Node
17:? ? ? ? 565584? ? ? ? 9049344? org.json.JSONArray
其中:字符數(shù)組钱慢,字符串對象,hashmap節(jié)點卿堂,字節(jié)數(shù)據(jù)滩字,jsonobject,arraylist御吞,url等占的對象較大麦箍。
3,分析總結(jié)
結(jié)合業(yè)務(wù)特點(具體業(yè)務(wù)需要保密)陶珠,核心機(jī)制包括兩點:
a挟裂,數(shù)據(jù)讀取,轉(zhuǎn)換揍诽,占用大量字符數(shù)組诀蓉,字符串對象栗竖,json對象。
b渠啤,數(shù)據(jù)計算狐肢,占用大量的HashMap,ArrayList沥曹。
總結(jié):
1份名,優(yōu)化方向一,優(yōu)化數(shù)據(jù)對象的大小和數(shù)目妓美,使之和當(dāng)前進(jìn)程配置參數(shù)“和諧共處”僵腺,避免oom,避免gc頻繁壶栋;后續(xù)繼續(xù)使用工具觀察gc情況辰如;
2,優(yōu)化方向二贵试,計算模塊不要亂用容器類琉兜,相當(dāng)占資源。