我有以下代码用于读取大约300MB大小的文件,执行过程由一个";java.lang.OutOfMemoryError:java堆空间"异常:
import java.io.*;
import java.util.*;
class MainClass {
static ArrayList<String> getAttribute(String str) {
if(str==null) return null;
ArrayList<String> a = new ArrayList<>();
int i = 0;
int j = -1;
while(i<str.length() && j<str.length()) {
j = str.indexOf(',',i);
if(j==-1) j = str.length();
a.add(str.substring(i,j));
i = str.indexOf(',',j)+1;
}
return a;
}
static ArrayList<ArrayList<String>> readFile(String in) throws IOException {
ArrayList<ArrayList<String>> a = new ArrayList<>();
try(FileInputStream fin = new FileInputStream(in);) {
BufferedReader br = new BufferedReader(new InputStreamReader(fin));
String str = br.readLine();
while(str!=null) {
a.add(getAttribute(str));
str = br.readLine(); //line 26
}
}
return a;
}
public static void main(String args[]) throws IOException
{
readFile("stats1.csv"); //line 34
}
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at MainClass.readFile(MainClass.java:26)
at MainClass.main(MainClass.java:34)
这个错误的原因是什么?还是只是文件太大?
查看ArrayList
类的默认构造函数的源代码,该构造函数不带参数。它创建一个大小为10的数组。然后查看类ArrayList
中方法add((的源代码。一旦添加了十个元素,就需要增加数组。它增加了一半。换句话说,当添加第十一个元素时,数组的大小将增加到15。当你添加第十六个元素时,数组会增加到22,依此类推。一旦你的数字很大,添加一个元素会导致数组大小大幅增加。因此,建议使用接受初始容量参数的ArrayList
构造函数。因此,也许您可以计算文件中的行数,以了解ArrayList
所需的容量。请参阅SO问题Java NIO Files count((计算行数的方法,了解计算文件中行数的一种方法。