如何在我的Java应用程序中查找内存泄漏 [英] How to find memory leaks in my Java application

查看:115
本文介绍了如何在我的Java应用程序中查找内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我上一个问题此处的后续问题.我目睹了Java应用程序中的内存泄漏.最初,我以为泄漏是由应用程序的服务器组件引起的.但是按照其他人的建议,事实并非如此.

This is a follow-up question from my previous question HERE. I was witnessing memory leaks in my Java application. Initially, I was thinking that the leak is coming from the Server component of my application. But as per other's suggestion, it wasn't.

我使用了一个工具来转储堆内存并使用JProfiler对其进行可视化.显然是由于我怀疑HashMaps.但是我不确定如何解释转储.

I used a tool to dump the heap memory and visualize it with JProfiler. Apparently it is due to my suspected HashMaps. But I'm not sure as I'm not familiar how to interpret the dump.

这是我的应用程序结构的简短摘要(它每15分钟缓存一些文本数据以快速检索服务器线程).

Here is a brief snippet of my application's structure (it is caching some text data every 15 mins for fast retrieval of a server thread).

是什么引起泄漏问题?以及如何从下面的转储中识别它? 显然我new Object()HashMap.put()的方式存在一些泄漏问题?!

What is causing the leak problem? And how to identify it from the dump below? Apparently the way I do new Object() and HashMap.put() has some leaking problems?!

第一个入门班/主要.在这里,我启动了7个主要的HashMaps,每个都将一个键(现在只有一个-最终将有16个键)映射到大约4000个单线JSON字符串的时间序列NavigableMap.

First starter class/main. Here I initiate 7 main HashMaps, each mapping a key (right now only one- eventually will have 16 keys) to a time-series NavigableMap of around 4000 one-liner JSON Strings.

public class MyCache {
        static HashMap <String, NavigableMap <Long, String>> map1= new HashMap <String, NavigableMap <Long, String>> ();
        static HashMap <String, NavigableMap <Long, String>> map2= new HashMap <String, NavigableMap <Long, String>> ();
        static HashMap <String, NavigableMap <Long, String>> map3= new HashMap <String, NavigableMap <Long, String>> ();
        static HashMap <String, NavigableMap <Long, String>> map4= new HashMap <String, NavigableMap <Long, String>> ();
        static HashMap <String, NavigableMap <Long, String>> map5= new HashMap <String, NavigableMap <Long, String>> ();
        static HashMap <String, NavigableMap <Long, String>> map6= new HashMap <String, NavigableMap <Long, String>> ();
        static HashMap <String, NavigableMap <Long, String>> map7= new HashMap <String, NavigableMap <Long, String>> ();

        public static void main(String[] args) throws Exception {
    new Server();
    new Aggregation();
    }
}

然后在Aggregation()中,我从HTTP资源中获取一些文本,将它们转换为JSON字符串,并将其缓存在一些临时的NavigableMaps中,然后将其放入主HashMap中(因此刷新不会对服务器的影响很大.

And then in Aggregation(), I get some texts from a HTTP resource, convert them to JSON strings, and cache them in some temporary NavigableMaps, then put them in the main HashMap (so refreshing won't affect server much).

public class Aggregation {
    static NavigableMap <Long, String> map1Temp= new ConcurrentSkipListMap <Long, String> ();;
    static NavigableMap <Long, String> map2Temp = new ConcurrentSkipListMap <Long, String> ();
    static NavigableMap <Long, String> map3Temp= new ConcurrentSkipListMap <Long, String> ();
    static NavigableMap <Long, String> map4Temp= new ConcurrentSkipListMap <Long, String> ();
    static NavigableMap <Long, String> map5Temp = new ConcurrentSkipListMap <Long, String> ();
    static NavigableMap <Long, String> map6Temp = new ConcurrentSkipListMap <Long, String> ();
    static NavigableMap <Long, String> map7Temp = new ConcurrentSkipListMap <Long, String> ();

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 <Long, String> (map1Temp));
            MyCache.map2.put(channel, new ConcurrentSkipListMap <Long, String> (map2Temp));
            MyCache.map3.put(channel, new ConcurrentSkipListMap <Long, String>(map3Temp));
            MyCache.map4.put(channel, new ConcurrentSkipListMap <Long, String>(map4Temp));
            MyCache.map5.put(channel, new ConcurrentSkipListMap <Long, String> (map5Temp));
            MyCache.map6.put(channel, new ConcurrentSkipListMap <Long, String> (map6Temp));
            MyCache.map7.put(channel, new ConcurrentSkipListMap <Long, String> (map7Temp));

//printing the size of all Hashmap entries. They don't grow :-/
logger.info("\t"+"map1.size(): "+MyCache.map1.get(key).size());
logger.info("\t"+"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);
}

推荐答案

内存分析器告诉您,您拥有3个庞大的HashMap数据结构,它们占用大约8GB的RAM ...包括它们引用的闭包键和值对象.看起来它们可能是地图.

The memory analyser is telling you that you have 3 hulking great HashMap data structures occupying about 8GB of RAM ... including the closure key and value objects they refer to. It looks like they might be maps of maps.

这可能是您的内存泄漏的证据.您的应用程序正在向地图数据结构中添加越来越多的条目,并且(大概)没有删除它们.那是内存泄漏的一种形式.

That is probably the evidence of your memory leak. Your application is adding more, and more entries to the map data structures, and (presumably) not removing them. That is a form of memory leak.

(请注意,这是您在上一个问题中没有显示给我们的代码的一部分...)

(Note this is in part of the code that you didn't show us in your previous question ...)

这篇关于如何在我的Java应用程序中查找内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆