背景
近期線上web服務(wù)內(nèi)存占用較大,空間資源消耗很多??紤]到后續(xù)訪問壓力會越來越大,防止GC頻繁,OOM等內(nèi)存問題爆發(fā),提前分析內(nèi)存使用情況。
思路
思路1:重點(diǎn)對象進(jìn)行評估,預(yù)估其真實(shí)大小值,內(nèi)存可占大小。--探路
思路2:全局觀察數(shù)據(jù),分析堆中對象的大小,數(shù)目。--全局思考
思路3:結(jié)合思路1,思路2,理清業(yè)務(wù)邏輯,推斷內(nèi)存過大原因。--分析總結(jié)
步驟
1,探路
系統(tǒng)主要對外提供數(shù)據(jù)訪問服務(wù)。數(shù)據(jù)的讀取,計(jì)算和封裝等操作,經(jīng)驗(yàn)來說就是內(nèi)存占用的最大“元兄”。
簡單的計(jì)算數(shù)據(jù)對象大小的方法:對象序列化操作,計(jì)算值和真實(shí)值的比值約在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)存大小僅供參考,它依賴的對象是不會計(jì)算在內(nèi)的,不準(zhǔn)確。
結(jié)合實(shí)際業(yè)務(wù)場景,預(yù)估核心數(shù)據(jù)占內(nèi)存的使用大小。
2,全局思考
jmap是個不錯的jdk自帶的實(shí)時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é)點(diǎn),字節(jié)數(shù)據(jù),jsonobject,arraylist,url等占的對象較大。
3,分析總結(jié)
結(jié)合業(yè)務(wù)特點(diǎn)(具體業(yè)務(wù)需要保密),核心機(jī)制包括兩點(diǎn):
a,數(shù)據(jù)讀取,轉(zhuǎn)換,占用大量字符數(shù)組,字符串對象,json對象。
b,數(shù)據(jù)計(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)化方向二,計(jì)算模塊不要亂用容器類,相當(dāng)占資源。