异常:OutOfMemoryError:运行代码时的Java堆空间
我有一个应用程序,它形成所有可能的对,然后比较这些对,但是当我运行应用程序时,它给了我一个异常:OutOfMemoryError:Java堆空间。我尝试了-Xmx1500m,但异常情况不断出现。 生成对的代码如下所示异常:OutOfMemoryError:运行代码时的Java堆空间,java,out-of-memory,Java,Out Of Memory,我有一个应用程序,它形成所有可能的对,然后比较这些对,但是当我运行应用程序时,它给了我一个异常:OutOfMemoryError:Java堆空间。我尝试了-Xmx1500m,但异常情况不断出现。 生成对的代码如下所示 File file = ...; final Map<Pair, Collection<Integer>> lineNumbersByPair = new HashMap<Pair, Collection<Integer>>();
File file = ...;
final Map<Pair, Collection<Integer>> lineNumbersByPair = new HashMap<Pair, Collection<Integer>>();
/*
* Step 1: Read in the lines, one by one.
*/
Reader reader = new FileReader(file);
try {
BufferedReader bufferedReader = new BufferedReader(reader);
try {
String line;
int lineNumber = 0;
while ((line = bufferedReader.readLine()) != null) {
lineNumber++;
String[] tokens = line.split("\\s+");
int[] values = new int[tokens.length];
for (int i = 0; i < tokens.length; i++) {
values[i] = Integer.parseInt(tokens[i]);
}
for (int i = 0; i < values.length; i++) {
for (int j = i + 1; j < values.length; j++) {
Pair pair = new Pair(values[i], values[j]);
Collection<Integer> lineNumbers;
if (lineNumbersByPair.containsKey(pair)) {
lineNumbers = lineNumbersByPair.get(pair);
} else {
lineNumbers = new HashSet<Integer>();
lineNumbersByPair.put(pair, lineNumbers);
}
lineNumbers.add(lineNumber);
}
}
}
} finally {
bufferedReader.close();
}
} finally {
reader.close();
}
/*
* Step 2: Identify the unique pairs. Sort them according to how many lines they appear on (most number of lines to least number of lines).
*/
List<Pair> pairs = new ArrayList<Pair>(lineNumbersByPair.keySet());
Collections.sort(
pairs,
new Comparator<Pair>() {
@Override
public int compare(Pair pair1, Pair pair2) {
Integer count1 = lineNumbersByPair.get(pair1).size();
Integer count2 = lineNumbersByPair.get(pair2).size();
return count1.compareTo(count2);
}
}
);
Collections.reverse(pairs);
/*
* Step 3: Print the pairs and their line numbers.
*/
for (Pair pair : pairs) {
Collection<Integer> lineNumbers = lineNumbersByPair.get(pair);
if (lineNumbers.size() > 1) {
System.out.println(pair + " appears on the following lines: " + lineNumbers);
}
}
文件=。。。;
最终映射lineNumbersByPair=newhashmap();
/*
*第一步:逐行阅读。
*/
Reader Reader=新文件读取器(文件);
试一试{
BufferedReader BufferedReader=新的BufferedReader(读卡器);
试一试{
弦线;
int lineNumber=0;
而((line=bufferedReader.readLine())!=null){
lineNumber++;
字符串[]标记=line.split(\\s+);
int[]值=新的int[tokens.length];
for(int i=0;i1){
System.out.println(pair+”出现在以下行:“+行号”;
}
}
我正在读一个15mb左右的文件,它包含20000行单数字,每行大约有40个数字,它形成了每行所有可能的对。
有人知道如何解决这个问题吗?谢谢我的数学可能不好,但这可能就是你仍然没有空间的原因 所以每行40个数字,20000行=800000个数字 800000 C 2=31999600000个数字组合 一个
int
有4个字节,对于Pair
,每对至少有8个字节,然后将其添加到数据结构中
8字节*319999600000=2+TB
重读你的问题后,每一行与下一行是分开的
每行40个数字=>40C2=780个组合每行*20000行=1560000个可能的唯一对*8字节每对=119MB在最坏的情况下纯粹用于int
。再加上引用占用的内存,因为Java不允许在集合中使用基元类型
但在看了你们的节目后,我有一些建议:
为什么要将对
映射到集
?
如果您只对每个对的出现次数感兴趣,则不需要跟踪这些对出现的行号-您只需要存储它出现的次数
因此,在本例中,您希望将对
映射到整数
。这样可以减少所需的内存量
您关心这双鞋的订购吗?
您的for
循环似乎表明您不关心订购,即配对(30,45)与配对(45,30)相同。如果是这样,您应该根据对中的相对顺序创建对。可能首先基于最小值创建一个对
,以便每次遇到两个整数m和n时,总是将该对创建为对(m,n)
。另请参见下一节关于hashCode()
和equals()
您是否实现了Pair
的int hashCode()
和布尔等于(对象)
方法?
这可能是实际工作程序和中断程序之间的差异
在您的例子中,您希望Pair
对象测试逻辑相等性,因为它是一个自定义类,所以您必须重写并实现自己的equals(Object)
方法。您还需要重写hashCode()
,因为重写equals()
时必须始终这样做
这在优秀有效的Java中有详细介绍,下面是一个讨论这一点的章节示例:当数据变得太大而无法容纳内存时,唯一的方法就是使用扩展内存(HDD)。
在这里,您可以分区并存储在磁盘上,将每个分区的一小部分加载到内存中并进行搜索
或者你应该使用一种使用更少内存和更多处理器的算法。
1.搜索文件,搜索所有num,并创建一个相对的二维矩阵或类似的东西
1 2 3 4 ...
1 0 1 0 0
2 0 1 0 0
3 0 0 0 0
...
2.您可以在此矩阵上排序。
3.一对一对地搜索文件,以获得包含两个数字的行num。
很抱歉,我的英语不好。对于较小的文件,您是否获得了正确的结果?到目前为止有成功的输出吗?是的,它在较小的文件上运行良好,并且输出都是goodstarcaller,正如J-16 SDiZ评论的和我发布的一样-这个问题就如同它一样