我正在编写一个需要读取非常大的文件(大约150Mb文本)的程序。当我尝试读取大于50Mb的文件时,我遇到了内存不足错误。以下是我的代码的摘录。
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile();
gui.setTitle("Fluent Helper - " + file.toString());
try{
scanner = new Scanner(new FileInputStream(file));
gui.getStatusLabel().setText("Reading Faces...");
while(scanner.hasNext()){
count++;
if(count<1000000){
System.gc();
count = 0;
}
readStr = scanner.nextLine()+ "\n";
if(readStr.equals("#\n")){
isFaces = false;
gui.getStatusLabel().setText("Reading Cells...");
}else if(isFaces){
faces.add(new Face(readStr));
}else{
cells.add(new Cell(readStr));
}
}
}catch (Exception e){
e.printStackTrace();
}finally{
try{
scanner.close();
}catch(Exception e){
e.printStackTrace();
}
}
System.out.println("flie selected");
} else {
System.out.println("file not selected");
}
调用垃圾收集器的每个任意数量的读取的小块是我为解决内存问题而添加的,但它不起作用。相反,程序挂起并且永远不会到达文件的单元格部分(这应该在不到一秒的时间内发生)。这是块。
if(count<1000000){
System.gc();
count = 0;
}
我的猜测是,扫描仪的指针可能正在收集垃圾或其他东西。我真的没有任何线索。使用更大的堆启动程序对我来说不是一个真正的选择。该计划应该由具有非常多计算机知识的人使用。
我想要一个解决方案来解决问题,无论是内存管理还是修复扫描程序或更有效的方法来读取文件。谢谢大家。
答案 0 :(得分:1)
GC会在需要时自动调用,因此自行调用只会降低应用程序的速度。
问题是您要保留的数据量
faces.add(new Face(readStr));
}else{
cells.add(new Cell(readStr));
这些超出了作为最大堆的内存量。您可以尝试设置-mx1g
,看看这是否有所作为?
顺便说一句:为什么要在每一行的末尾添加\n
?
答案 1 :(得分:1)
调用垃圾回收通常不是一个好主意,你可能想看看为什么:Why is it bad practice to call System.gc()?
您是否尝试过增加最大堆大小,例如使用-Xmx:1g进行1千兆字节?