我正在尝试读取文件并将共享相同第一个标记(readId)的行保存在一组(字符串)中。每组都是我的 HashMap 的一部分 >.
我已经将堆增加到 32 giga,也从 string.split 移动到 StringTokenizer,但仍然遇到此错误:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:2694)
at java.lang.String.<init>(String.java:203)
at java.lang.String.substring(String.java:1913)
at java.util.StringTokenizer.nextToken(StringTokenizer.java:352)
at java.util.StringTokenizer.nextElement(StringTokenizer.java:407)
at Simple1_BootStrap.createMapSet(Simple1_BootStrap.java:68)
at Simple1_BootStrap.main(Simple1_BootStrap.java:206)
以前,“内存不足错误”是由以下行生成的:
Set<String> s =new TreeSet<String>();
产生错误的代码片段是:
Map<String,Set<String>> map2 = new HashMap<String,Set<String>>();
try{
BufferedReader br = new BufferedReader(new FileReader(filename));
String strLine;
String readId;
while ((strLine = br.readLine()) != null) {
alignment ++;
StringTokenizer stringTokenizer = new StringTokenizer(strLine);
readId = stringTokenizer.nextElement().toString();
if(map2.containsKey(readId)) {
Set<String> s = map2.get(readId);
s.add(strLine);
map2.put(readId, s);
}
else {
Set<String> s =new TreeSet<String>();
s.add(strLine);
map2.put(readId, s);
}
}
br.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
我将这些行放入一个集合中,因为我需要随机选择散列图中的条目并读取关联的集合以创建类似于输入文件的文件。
有人可以建议另一种方法来避免“内存不足错误”吗?
谢谢。
最佳答案
无论将所有内容加载到内存中是否明智,String.substring()
都会保留对最近版本的 Java 7 之前的 Java 版本的原始(较大)字符串的引用。所持有的内存可能比您想象的多多。请参阅this question/answer了解更多详情。
使用 String(String)
构造函数从 StringTokenizer
结果构建新字符串将缓解这种情况,升级到最新的 Java 7 运行时也是如此。
关于java - 在Java中使用Hashmap with set读取大文件(20G)——Java堆空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19982565/