0

我正在编写一个需要读取非常大的文件(大约 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;
                }

我的猜测是,也许扫描仪的指针正在收集垃圾或其他东西。我真的一点头绪都没有。用更大的堆启动程序对我来说并不是一个真正的选择。该程序应该可供没有太多计算机知识的人使用。

我想要一个解决方案来让文件没有问题,无论是内存管理还是修复扫描仪或更有效的读取文件的方法。谢谢大家。

4

2 回答 2

1

GC 将在需要时自动调用,因此您自己调用它只会减慢您的应用程序的速度。

问题是您保留的数据量

                faces.add(new Face(readStr));
            }else{
                cells.add(new Cell(readStr));

这些超出了您作为最大堆的内存量。你可以尝试设置-mx1g看看这是否有影响吗?

顺便说一句:你为​​什么\n要在每行的末尾添加一个?

于 2012-06-15T13:32:39.010 回答
1

调用垃圾收集通常不是一个好主意,您可能想在这里看看为什么:为什么调用 System.gc() 是不好的做法?

您是否尝试过增加最大堆大小,例如将 -Xmx:1g 用于 1 GB?

于 2012-06-15T13:43:56.023 回答