写了段小程序,读一个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都是重复存储...占用多了实际文件的一倍..