Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-读取大型csv文件时发生OutofMemoryError_Java_Csv_Memory - Fatal编程技术网

Java-读取大型csv文件时发生OutofMemoryError

Java-读取大型csv文件时发生OutofMemoryError,java,csv,memory,Java,Csv,Memory,我想用Java读取一个巨大的csv文件。它包括75000000行。问题是,即使我使用了最大xms和xmx限制,我还是得到了:`java.lang.OutOfMemoryError(超出了GC开销限制),它显示这一行导致了错误: String[][] matrix = new String[counterRow][counterCol]; 我做了一些测试,发现我能很好地阅读15000000行。因此,我开始使用这种代码: String csvFile = "myfile.csv"; List<

我想用Java读取一个巨大的
csv
文件。它包括75000000行。问题是,即使我使用了最大
xms
xmx
限制,我还是得到了:`java.lang.OutOfMemoryError(超出了GC开销限制),它显示这一行导致了错误:

String[][] matrix = new String[counterRow][counterCol];
我做了一些测试,发现我能很好地阅读15000000行。因此,我开始使用这种代码:

String csvFile = "myfile.csv";
List<String[]> rowList = new ArrayList();
String line = "";
String cvsSplitBy = ",";
BufferedReader br = null;
try {
    int counterRow = 0, counterCol = 12, id = 0;
    br = new BufferedReader(new FileReader(csvFile));
    while ((line = br.readLine()) != null) { 
        String[] object = line.split(cvsSplitBy);
        rowList.add(object); 
        counterRow++;
        if (counterRow % 15000000 ==0) {
            String[][] matrix = new String[counterRow][counterCol];
            .. do processes ..
            SaveAsCSV(matrix,id);
            counterRow=0; id++; rowList.clear();
        }
    }
}
...
String csvFile=“myfile.csv”;
List rowList=new ArrayList();
字符串行=”;
字符串cvsSplitBy=“,”;
BufferedReader br=null;
试一试{
int计数器行=0,计数器列=12,id=0;
br=新的BufferedReader(新的文件读取器(csvFile));
而((line=br.readLine())!=null){
String[]object=line.split(cvsSplitBy);
添加(对象);
柜台++;
如果(计数器行%15000000==0){
字符串[][]矩阵=新字符串[计数器行][计数器列];
…执行流程。。
SaveAsCSV(矩阵,id);
计数器行=0;id++;行列表.clear();
}
}
}
...
在这里,它很好地写出了前15000.000.000行,但在第二次试验中,它再次给出了相同的错误,尽管计数器行是15000000

总之,我需要在Java中读取一个包含75000000行(约5 GB)的
csv
文件,并在对其记录进行一些处理后保存一个或多个新的
csv
文件

我怎样才能解决这个问题

谢谢

编辑:我也在使用rowList.clear()伙计们,忘记在这里指定了。对不起


编辑2:我的朋友们,我不需要把所有的文件都放在内存中。我怎么能一部分一部分地读呢。实际上,这就是我尝试使用if(计数器行%15000000==0)所做的。正确的方法是什么?

您可以单独读取行,然后进行处理,直到读取整个文件

String encoding = "UTF-8";
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("/bigfile.txt"), encoding));
String line;
while ((line = br.readLine()) != null) {
   // process the line.
}
br.close();

这不应该变成fubar,只要确保您立即处理它,不要将它存储在循环外部的变量中

您可以单独读取行,然后进行处理,直到读取整个文件为止

String encoding = "UTF-8";
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("/bigfile.txt"), encoding));
String line;
while ((line = br.readLine()) != null) {
   // process the line.
}
br.close();

这不应该发生在fubar中,只要确保您立即处理它,并且不要将它存储在循环外部的变量中

问题不在于您没有足够的内存,“超出了GC开销限制”问题意味着垃圾收集花费的时间太长。您无法通过分配更多内存来解决此问题,而只能使用
-XX:-usegcoveredlimit
。也就是说,如果你真的想在内存中存储那么多数据

见例


或者使用peter lawrey的内存映射HugeCollections::如果内存已满,它会写入磁盘。

问题不是您没有足够的内存,“超出GC开销限制”问题意味着垃圾收集时间过长。您无法通过分配更多内存来解决此问题,而只能使用
-XX:-usegcoveredlimit
。也就是说,如果你真的想在内存中存储那么多数据

见例


或者使用peter lawrey的内存映射HugeCollections::如果内存已满,它将写入磁盘。

也许您忘记调用了

rowList.clear();
之后


也许你忘了打电话了

rowList.clear();
之后


当您的应用程序耗尽了几乎所有的可用内存,并且GC多次未能清除时,将显示“java.lang.OutOfMemoryError:GC开销限制已超出”错误

上面推荐的解决方案-指定-XX:-usegcoveredlimit是我强烈建议不要做的事情。你不是在解决问题,而是在推迟不可避免的事情:应用程序内存不足,需要修复。指定此选项只会用更熟悉的消息“java.lang.OutOfMemoryError:java堆空间”掩盖原始的“java.lang.OutOfMemoryError:GC开销限制已超出”错误


在您的情况下,可能的解决方案可以归结为两种合理的选择—要么增加堆空间(-Xmx参数),要么通过小批量读取文件来减少代码的堆消耗。

java.lang.OutOfMemoryError:超出GC开销限制当您的应用程序耗尽了几乎所有的可用内存,并且GC多次未能清除内存时,将显示错误

上面推荐的解决方案-指定-XX:-usegcoveredlimit是我强烈建议不要做的事情。你不是在解决问题,而是在推迟不可避免的事情:应用程序内存不足,需要修复。指定此选项只会用更熟悉的消息“java.lang.OutOfMemoryError:java堆空间”掩盖原始的“java.lang.OutOfMemoryError:GC开销限制已超出”错误


在您的情况下,可能的解决方案可以归结为两种合理的选择—要么增加堆空间(-Xmx参数),要么通过小批量读取文件来减少代码的堆消耗。

内存中有大量数据—为什么不尝试写入数据库,然后查询它?你肯定不能把整个该死的文件放到内存里。是否可以批量/部分处理文件?内存映射文件?如果你的文件是5GB,你想把它保存在内存中,你就需要领先5GB的RA%我想,巨量的^^
流媒体
是你最好的朋友这里有大量的数据要存储在内存中-你为什么不试着写入数据库,然后查询它?你肯定不能把整个该死的文件都存储在内存中。是否可以批量/部分处理文件?内存映射文件?如果您的文件是5GB,并且您希望将其保留在内存中,那么您将需要领先5GB的RA%,我认为,巨大的^^^
流媒体
是您最好的朋友,这一点很好。我正在使用rowList.clear()还有,忘了在这里复制/粘贴!啊,说得好。我正在使用rowList.clear()还有,忘了在这里复制/粘贴!啊,说得好。我正在使用rowList.clear()还有,忘了在这里复制/粘贴!啊,说得好。我正在使用rowList.clear()还有,忘了