![](/img/trans.png)
[英]Problems reading a huge file of 12 MB (java.lang.OutOfMemoryError)
[英]Java - OutofMemoryError while reading a huge csv file
我想通过Java读取庞大的csv
文件。 它包括75,000,000行。 问题是,即使我用最大的xms
和xmx
限制,我得到:`java.lang.OutOfMemoryError(GC开销超过限制),它显示了该行导致错误:
String[][] matrix = new String[counterRow][counterCol];
我做了一些测试,发现我可以很好地阅读15,000,000行。 因此,我开始使用这种代码:
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();
}
}
}
...
在这里,它很好地写入了第一行15.000.000行,但是在第二次尝试中,尽管counterRow为15,000,000,但它再次给出了相同的错误。
总之,我需要在Java中读取包含75,000,000行(约5 GB)的csv
文件,并在对其记录进行某些处理后保存一个或多个新的csv
文件。
我怎么解决这个问题?
谢谢
编辑:我也使用rowList.clear()伙计们,忘了在这里指定。 抱歉。
编辑2:我的朋友们,我不需要将所有文件都放在内存中。 我如何才能部分地阅读它。 实际上,这就是我尝试使用if(counterRow%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();
这不应该只是为了确保您立即进行,并且不要将其存储在循环外的变量中
问题不是您没有足够的内存,问题“超出了GC开销限制”意味着垃圾收集花费的时间太长。 您不能通过分配更多的内存来解决此问题,而只能使用-XX:-UseGCOverheadLimit
。 也就是说,如果您确实要在内存中存储那么多数据。
请参见例如如何使用maven jvmArg解决“超出了GC开销限制”?
或使用彼得·劳里(Peter Lawrey)的内存映射HugeCollection: http ://vanillajava.blogspot.be/2011/08/added-memory-mapped-support-to.html?q=huge+collections:如果内存已满,它将写入磁盘。
也许你忘了打电话
rowList.clear();
后
counterRow=0; id++;
当您的应用程序几乎耗尽了所有可用内存并且GC反复无法清除它时,将显示“ java.lang.OutOfMemoryError:超出GC开销限制”错误。
我强烈建议您不要执行上述建议的解决方案-指定-XX:-UseGCOverheadLimit 。 而不是解决问题,您只是推迟了不可避免的事情:应用程序内存不足,需要修复。 指定此选项仅会掩盖原始的“ java.lang.OutOfMemoryError:GC超出开销限制 ”错误,并显示更熟悉的消息“ java.lang.OutOfMemoryError:Java堆空间 ”。
在您的情况下,可能的解决方案大致归结为两个合理的选择-增加堆空间(-Xmx参数)或通过小批量读取文件来减少代码的堆消耗。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.