我正在尝试创建一个邻接表来存储图形。在存储100,000条记录时,实现工作正常。然而,当我尝试存储大约1百万条记录时,我遇到了内存溢出错误:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange(Arrays.java:3209) at java.lang.String.(String.java:215) at java.io.BufferedReader.readLine(BufferedReader.java:331) at java.io.BufferedReader.readLine(BufferedReader.java:362) at liarliar.main(liarliar.java:39)
以下是我的实现:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange(Arrays.java:3209) at java.lang.String.(String.java:215) at java.io.BufferedReader.readLine(BufferedReader.java:331) at java.io.BufferedReader.readLine(BufferedReader.java:362) at liarliar.main(liarliar.java:39)
以下是我的实现:
HashMap<String,ArrayList<String>> adj = new HashMap<String,ArrayList<String>>(num);
while ((str = in.readLine()) != null)
{
StringTokenizer Tok = new StringTokenizer(str);
name = (String) Tok.nextElement();
cnt = Integer.valueOf(Tok.nextToken());
ArrayList<String> templist = new ArrayList<String>(cnt);
while(cnt>0)
{
templist.add(in.readLine());
cnt--;
}
adj.put(name,templist);
} //done creating a adjacency list
我在想,是否有更好的方法来实现邻接表。此外,我知道节点数目在一开始就确定了,并且在访问节点时我会将列表展开。你有什么建议吗?
谢谢!
Map<String,Integer>
查找是便宜的(O(1)
);除非已经证明是问题,否则不应该被打扰。过早优化是万恶之源。在这种情况下更是如此,因为你还没有发现一个_BIG_优化。你理解得对:你根本不需要创建邻接表。你可以用O(V)
的空间解决这个问题。你可以在O(V+E)
的时间内处理输入(这是最优的,因为这是输入的大小),在读完输入后,你可以立即以O(1)
的时间产生输出。 - polygenelubricants.intern()
来代替Map<String,Integer>
。输入中会有很多重复的名称,它们在内存中被多次冗余存储。如果只存储这些名称的.intern()
,那么冗余副本将被垃圾回收。而且,如果您始终.intern()
这些名称,就可以使用==
和!=
而不是equals()
。了解字符串驻留的工作原理。虽然这只是一个小的时间优化,但真正重要的是上面评论中提到的那个。 - polygenelubricants