首先需要一个查看内存命令:jmap -histo:live pid
优化策略:
一.查看占用内存原因:
1.大量String对象
2.大量QElement对象
二,优化策略:
1.string.intern(),利用string 常量池,可见前文章 高并发高负载基础篇之 String 详细分析
2.将QElement拆分成 index 和 QElemntmin,实现一个QElement常量池
private QElement() {
}
// 唯一键是unique(id, index)
private String index;
private QElementMin qElementMin;
private static int ELEMENT_ARRAY_LIST_SIZE = 1000;
public static List<QElementMin>[] elementList = new List[ELEMENT_ARRAY_LIST_SIZE];
static {
for (Integer i = 0; i < ELEMENT_ARRAY_LIST_SIZE; i++) {
elementList[i] = Lists.newArrayList();
}
}
public static QElement getInstance(int id, String name, String tag, String searchIndex, long score, String seq,
Set<AppEnum> app, boolean poiInName) {
QElementMin elementMin = new QElementMin(id, name, tag, score, seq, app, poiInName);
List<QElementMin> tmp = elementList[id % ELEMENT_ARRAY_LIST_SIZE];
int index = Collections.binarySearch(tmp, elementMin);
if (index < 0) {
index = Math.abs(index + 1);
tmp.add(index, elementMin);
}
QElement element = new QElement();
element.setIndex(searchIndex.intern());
element.setqElementMin(tmp.get(index));
return element;
}
优化之前:
num #instances #bytes class name
----------------------------------------------
1: 20651748 819202088 [C
2: 24415146 781284672 java.lang.String
3: 12830189 615849072 com.qunar.hotel.qtypeahead.datastructure.QElement
4: 12831843 513273720 java.util.TreeMap$Entry
5: 3751691 300813168 [Ljava.util.HashMap$Entry;
6: 3750536 180025728 java.util.HashMap
7: 3708672 59338752 java.util.HashSet
8: 1676514 53648448 java.util.HashMap$Entry
9: 2802044 44832704 java.util.HashMap$KeySet
10: 10972 12019864 [B
11: 59737 9314320 <constMethodKlass>
12: 59737 8134040 <methodKlass>
13: 7586 7478800 [I
14: 5346 6132976 <constantPoolKlass>
15: 95003 5672768 <symbolKlass>
16: 130786 4185152 java.util.concurrent.ConcurrentHashMap$HashEntry
17: 73559 4119304 org.apache.tomcat.util.buf.MessageBytes
。。。。。。。。。。。。。。。。。。
2084: 1 16 java.util.Hashtable$EmptyIterator
2085: 1 16 $Proxy7
2086: 1 16 org.springframework.context.support.ApplicationContextAwareProcessor$EmbeddedValueResolver
2087: 1 16 org.apache.log4j.helpers.AppenderAttachableImpl
2088: 1 16 org.apache.http.client.protocol.RequestAddCookies
2089: 1 16 com.sun.org.apache.xerces.internal.impl.dv.xs.PrecisionDecimalDV
2090: 1 16 org.codehaus.jackson.map.type.TypeParser
2091: 1 16 sun.reflect.GeneratedMethodAccessor2
2092: 1 16 org.apache.http.impl.auth.DigestSchemeFactory
Total 87409833 3456431712
可以看到内存为3.4G
优化之后:
num #instances #bytes class name
----------------------------------------------
1: 13111239 524449560 java.util.TreeMap$Entry
2: 10119832 492655664 [C
3: 13109559 314629416 com.qunar.hotel.qtypeahead.datastructure.QElement
4: 10118546 242845104 java.lang.String
5: 3839301 184286448 java.util.HashMap
6: 3797086 182260128 com.qunar.hotel.qtypeahead.datastructure.QElementMin
7: 1562086 125744048 [Ljava.util.HashMap$Entry;
8: 3797734 60763744 java.util.HashSet
9: 3797667 60762672 java.util.HashMap$KeySet
10: 1685967 53950944 java.util.HashMap$Entry
11: 5610 17409912 [Ljava.lang.Object;
12: 16568 9097504 [B
13: 58258 8419008 <constMethodKlass>
14: 58258 7467824 <methodKlass>
15: 1242 7090472 [I
16: 5469 6218048 <constantPoolKlass>
17: 138609 4435488 java.util.concurrent.ConcurrentHashMap$HashEntry
。。。。。。。。。。。。。。。。。。。。。。。。。。
2317: 1 16 com.alibaba.fastjson.parser.deserializer.AtomicIntegerArrayDeserializer
2318: 1 16 org.apache.http.impl.auth.DigestSchemeFactory
2319: 1 16 org.apache.http.impl.client.DefaultTargetAuthenticationHandler
2320: 1 16 org.codehaus.jackson.map.deser.std.StdKeyDeserializer$UuidKD
2321: 1 16 com.alibaba.fastjson.parser.deserializer.TreeMapDeserializer
2322: 1 16 sun.nio.cs.CharsetMapping$2
2323: 1 16 org.codehaus.jackson.map.deser.std.StdDeserializer$StackTraceElementDeserializer
2324: 1 16 sun.reflect.GeneratedMethodAccessor15
2325: 1 16 sun.reflect.GeneratedConstructorAccessor18
Total 65622574 2324748952
内存为2.3G