这是我先前的问题HERE的后续问题.我目睹Java应用程序中的内存泄漏.最初,我以为泄漏来自应用程序的服务器组件.但是按照其他人的建议,事实并非如此.
我使用了一个工具来转储堆内存并使用JProfiler对其进行可视化.显然这是由于我怀疑有HashMaps.但是我不确定,因为我不熟悉如何解释转储.
这是我的应用程序结构的简短摘要(它每15分钟缓存一些文本数据以快速检索服务器线程).
是什么引起泄漏问题?以及如何从下面的转储中识别它?
显然我做new Object()和HashMap.put()的方式有一些泄漏问题吗?
初级入门班/主要.在这里,我启动了7个主要的HashMap,每个映射一个键(现在只有一个,最终将有16个键)映射到大约4000个单线JSON字符串的时间序列NavigableMap.
public class MyCache {
static HashMap > map1= new HashMap > ();
static HashMap > map2= new HashMap > ();
static HashMap > map3= new HashMap > ();
static HashMap > map4= new HashMap > ();
static HashMap > map5= new HashMap > ();
static HashMap > map6= new HashMap > ();
static HashMap > map7= new HashMap > ();
public static void main(String[] args) throws Exception {
new Server();
new Aggregation();
}
}
然后在Aggregation()中,我从HTTP资源中获取一些文本,将其转换为JSON字符串,并将其缓存在一些临时的NavigableMaps中,然后将其放入主HashMap中(因此刷新不会对服务器造成太大影响).
public class Aggregation {
static NavigableMap map1Temp= new ConcurrentSkipListMap ();;
static NavigableMap map2Temp = new ConcurrentSkipListMap ();
static NavigableMap map3Temp= new ConcurrentSkipListMap ();
static NavigableMap map4Temp= new ConcurrentSkipListMap ();
static NavigableMap map5Temp = new ConcurrentSkipListMap ();
static NavigableMap map6Temp = new ConcurrentSkipListMap ();
static NavigableMap map7Temp = new ConcurrentSkipListMap ();
public Aggregation(){
// loop to cache last 15 mins
while (true) {
logger.info("START REFRESHING ...");
for (int i = 0; i < mylist.size(); i++) {
long startepoch = getTime(mylist.get(i).time);
MyItem m = mylist.get(i);
String index=(i+1)+"";
process1(index, m.name, startepoch);
//adds to map1Temp
process2(index, m.name, startepoch);
//adds to map2Temp
process3(index, m.name, startepoch);
//adds to map3Temp
process4(index, m.name, startepoch);
//adds to map4Temp
process5(index, m.name, startepoch);
//adds to map5Temp
process6(index, m.name, startepoch);
//adds to map6Temp
process7(index, m.name, startepoch);
//adds to map7Temp
}
//then `put` them in the main `HashMap` all at-once:
MyCache.map1.put(channel, new ConcurrentSkipListMap (map1Temp));
MyCache.map2.put(channel, new ConcurrentSkipListMap (map2Temp));
MyCache.map3.put(channel, new ConcurrentSkipListMap (map3Temp));
MyCache.map4.put(channel, new ConcurrentSkipListMap (map4Temp));
MyCache.map5.put(channel, new ConcurrentSkipListMap (map5Temp));
MyCache.map6.put(channel, new ConcurrentSkipListMap (map6Temp));
MyCache.map7.put(channel, new ConcurrentSkipListMap (map7Temp));
//printing the size of all Hashmap entries. They don't grow :-/
logger.info(""+"map1.size(): "+MyCache.map1.get(key).size());
logger.info(""+"map2.size(): "+MyCache.map2.get(key).size());
//and other 5...
//then clear the temp maps so they don't grow over and over
map1Temp.clear();
map2Temp.clear();
map3Temp.clear();
map4Temp.clear();
map5Temp.clear();
map6Temp.clear();
map7Temp.clear();
}
//sleep for 15 min until next caching cycle
Thread.sleep(cacheEvery*1000*60);
}