日期:2014-05-20  浏览次数:20706 次

50行java程序,内存吃在哪?
写了段小程序,读一个300M左右的文件,共100万个不同id结点,2200万行。文件内容只有两列,如下:
3,6
3,7
3,16
20,31
20,35
20,36
……

其中3,6表示id为3的用户关注了id为6的用户。我写的程序是把这个文件读入内存,接收的数据结构有三个:
HashSet<Integer> set //结点id的集合
HashMap<Integer, LinkedList<Integer>> inlinkMap //映射关系为 id->follower ids
HashMap<Integer, LinkedList<Integer>> outlinkMap //映射关系为 id->followee ids


代码如下:(关键代码只有中间一小段,前面是变量定义,后面是异常处理)
Java code

private void format(String fileName, Set<Integer> set, HashMap< Integer, LinkedList<Integer> > inlinkMap, 
            HashMap<Integer,LinkedList<Integer> > outlinkMap)
    {
        System.out.println("Loading...");
        FileReader fr = null;
        BufferedReader br = null;
        LinkedList<Integer> inlinkList = null;
        LinkedList<Integer> outlinkList = null;        
        String strLine = null;
        int seperatorIndex, followerId, followeeId;
        
        try {
            fr = new FileReader(fileName);
            br = new BufferedReader(fr);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        while(true)
        {
            try
            {
                strLine = br.readLine();
                seperatorIndex = strLine.indexOf(',');
                followerId = Integer.parseInt(strLine.substring(0, seperatorIndex));
                followeeId = Integer.parseInt(strLine.substring(seperatorIndex+1,strLine.length()));
                
                if(!set.contains(followerId))
                {
                    set.add(followerId);
                }
                if(!set.contains(followeeId))
                {
                    set.add(followeeId);
                }
                
                if(!inlinkMap.keySet().contains(followeeId))
                {
                    inlinkList = new LinkedList<Integer>();
                    inlinkList.add(followerId);
                    inlinkMap.put(followeeId, inlinkList);                    
                }
                else
                {
                    inlinkList = inlinkMap.get(followeeId);
                    inlinkList.add(followerId);
                }
                
                if(!outlinkMap.keySet().contains(followerId))
                {
                    outlinkList = new LinkedList<Integer>();
                    outlinkList.add(followeeId);
                    outlinkMap.put(followerId, outlinkList);
                }
                else
                {
                    outlinkList = outlinkMap.get(followerId);
                    outlinkList.add(followeeId);
                }
                
            } catch(Exception e)
            {
                System.out.println("EOF");
                try {
                    br.close();
                    fr.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                break;
            }
        }
        try {
            br.close();
            fr.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Loading completed!");

    }



运行的时候,我用java -Xms2048m -Xmx8192m XXXXX 命令,分配了8G的内存才能成功,8G以下都提示内存不足
是不是用HashMap太占内存了?还是我用HashMap的方法不对?
求解脱……

------解决方案--------------------
HashMap<Integer, LinkedList<Integer>> inlinkMap //映射关系为 id->follower ids
HashMap<Integer, LinkedList<Integer>> outlinkMap //映射关系为 id->followee ids

占内存,每一个ID对应一个新的链表对象...链表的对象对而大。
比如:1对应234567890
2对应134567890。。。里面的34567890都是重复存储...占用多了实际文件的一倍..