我需要浏览大约3000个文件夹,每个文件夹包含300个CSV文件。
这是((nextLine=csvReader.readNext()) != null)
时行发生的错误:
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at au.com.bytecode.opencsv.CSVParser.parseLine(CSVParser.java:206)
at au.com.bytecode.opencsv.CSVParser.parseLineMulti(CSVParser.java:174)
at au.com.bytecode.opencsv.CSVReader.readNext(CSVReader.java:237)
at DA.readTelemetryData(DA.java:78)
at DA.main(DA.java:24)
问题是如何解决这个问题?为什么会出现问题?我的代码出了什么问题?
我在这里提供代码:
private static HashMap<Integer,HashMap<Integer,List<double[]>>> readTelemetryData() throws Exception
{
HashMap<Integer,HashMap<Integer,List<double[]>>> xy_total = new HashMap<Integer,HashMap<Integer,List<double[]>>>();
for (int i=0; i<Constants.MAX_FOLDERS; i++)
{
HashMap<Integer,List<double[]>> xy_total_per_folder= new HashMap<Integer,List<double[]>>();
for (int j=0; j<Constants.MAX_FILES_INSIDE_FOLDER; j++)
{
CSVReader csvReader = null;
File f = new File("data/"+ (i+1) +"/"+ (j+1) +".csv");
if(f.exists())
{
csvReader = new CSVReader(new FileReader(f));
List<double[]> xyArr = new ArrayList<double[]>();
String[] firstLine=csvReader.readNext();
if (firstLine != null)
{
String[] nextLine=null;
while ((nextLine=csvReader.readNext()) != null)
{
double[] d = new double[2];
d[0]=Double.parseDouble(nextLine[0]);
d[1]=Double.parseDouble(nextLine[1]);
xyArr.add(d);
}
}
xy_total_per_folder.put(j, xyArr);
csvReader.close();
}
}
xy_total.put(i, xy_total_per_folder);
}
return xy_total;
}
答案 0 :(得分:2)
你的内存不足。
HashMap<Integer,V>
是一个相当糟糕的选择。密钥需要16个字节,每个+死区的条目可能需要24个字节。您的double[]
则需要32个字节(用于存储16个字节的有效负载)。在数组列表中,您需要另外4个字节作为参考...
因此,例如,每行将花费您36个字节的16个实例。
考虑使用更紧凑的数据结构。 GNU Trove是一个为原始类型提供优秀集合的库;但是不要低估数组的价值......
用于处理大量原始类型(int
,double
等)远离java.util.
集合。相反,花些额外的时间来组织你的记忆。
例如,您可以使用Trove的TDoubleArrayList
,一个用于所有 x,一个用于所有 y值,而不是使用每行一个数组。读完文件后,可以将它们转换为最小double[] x; double[] y;
数组,并重用TDoubleArrayList
来解析下一个文件。
最后但并非最不重要的是,Java默认只使用25%的内存。使用-Xmx
来增加限制。
运行内存探查器。大部分内存分配在哪里?所有这些都需要吗?也许你正在使用的CSVReader有内存泄漏!使用内存分析器是一种简单的方法。
但是算一算。你有几行 - 可以你把所有这些都放到内存中吗?
答案 1 :(得分:0)
这种行为通常有两个原因:
内存泄漏。这意味着您可以编写不再需要的商店数据。分析内存转储以进行修复。
内存不足,因为你的程序实际上需要那么多内存。哟可以简单地给它更多的记忆。或者尝试更改算法和数据结构。