Java 文件读取:内存不足错误
我需要浏览大约3000个文件夹,每个文件夹包含300个CSV文件 这是在Java 文件读取:内存不足错误,java,filereader,opencsv,Java,Filereader,Opencsv,我需要浏览大约3000个文件夹,每个文件夹包含300个CSV文件 这是在((nextLine=csvReader.readNext())!=null)时发生的错误。: 问题是如何解决这个问题?为什么会发生这种情况?我的代码中有什么错误 我在这里提供代码: private static HashMap<Integer,HashMap<Integer,List<double[]>>> readTelemetryData() throws Exception
((nextLine=csvReader.readNext())!=null)时发生的错误。
:
问题是如何解决这个问题?为什么会发生这种情况?我的代码中有什么错误
我在这里提供代码:
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;
}
private static HashMap read遥测数据()引发异常
{
HashMap xy_total=新HashMap();
对于(int i=0;i您的内存不足
HashMap
是一个相当糟糕的选择。它需要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存在内存泄漏!使用内存探查器是一种很容易找到的方法
但是做个数学计算。你有多少行?你能把它们全部放进内存吗?这种行为通常有两个原因:
内存泄漏。这意味着您的程序存储了不再需要的数据。请分析内存转储以进行修复
内存不足,因为您的程序实际上需要那么多内存。您可以简单地给它更多内存。或者尝试更改您的算法和数据结构
你的问题是什么?@talex:问题是如何解决这个问题?为什么会出现这种情况?我的代码中有什么错误?我假设我应该避免使用HashMap,但我不确定。你的代码是可以的。如果你需要所有这些数据,这是一个简单的解决方案。增加内存限制。使用-XMX=1G
运行java。抱歉。标志是-XMX=1G
@talex:好的,谢谢。但是在这种情况下使用HashMap是个好主意吗?HashMap比数组慢很多吗?
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;
}