我读取大文本文件的Java程序内存不足,任何人都可以帮忙解释原因吗?

Wee*_*and 15 java

我有一个包含2000万行文本的大文本文件.当我使用以下程序读取文件时,它工作正常,实际上我可以读取更大的文件,没有内存问题.

public static void main(String[] args) throws IOException {
    File tempFile = new File("temp.dat");
    String tempLine = null;
    BufferedReader br = null;
    int lineCount = 0;
    try {
        br = new BufferedReader(new FileReader(tempFile));
        while ((tempLine = br.readLine()) != null) {
            lineCount += 1;
        }
    } catch (Exception e) {
        System.out.println("br error: " +e.getMessage());
    } finally {
        br.close();
        System.out.println(lineCount + " lines read from file");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我需要在读取之前将一些记录附加到此文件中,BufferedReader会消耗大量内存(我刚刚使用Windows任务管理器来监视这一点,我知道这不是很科学,但它证明了这个问题).修改后的程序如下,与第一个程序相同,只是我首先在文件中附加一条记录.

public static void main(String[] args) throws IOException {
    File tempFile = new File("temp.dat");
    PrintWriter pw = null;
    try {
        pw = new PrintWriter(new BufferedWriter(new FileWriter(tempFile, true)));
        pw.println(" ");
    } catch (Exception e) {
        System.out.println("pw error: " + e.getMessage());
    } finally {
        pw.close();
    }

    String tempLine = null;
    BufferedReader br = null;
    int lineCount = 0;
    try {
        br = new BufferedReader(new FileReader(tempFile));
        while ((tempLine = br.readLine()) != null) {
            lineCount += 1;
        }
    } catch (Exception e) {
        System.out.println("br error: " +e.getMessage());
    } finally {
        br.close();
        System.out.println(lineCount + " lines read from file");
    }
}
Run Code Online (Sandbox Code Playgroud)

Windows任务管理器的屏幕截图,当我运行第二个版本的程序时,行中的大凹凸显示内存消耗.

任务管理器截图

所以我能够在不耗尽内存的情况下读取此文件.但是我有更大的文件,超过5000万条记录,当我对它们运行这个程序时遇到内存不足的异常?有人可以解释为什么程序的第一个版本适用于任何大小的文件,但第二个程序行为如此不同并以失败告终?我在Windows 7上运行:

java版"1.7.0_05"
Java(TM)SE运行时环境(版本1.7.0_05-b05)
Java HotSpot(TM)客户端VM(版本23.1-b03,混合模式,共享)

Dan*_*Dan -3

你需要用更大的堆来启动java。尝试将 -Xmx1024m 作为 java 命令的参数。

基本上你需要的内存比文件的大小更多。

  • 你能解释一下为什么我的第二个程序需要更大的堆而不是第一个程序?该程序的第一个版本运行得很好,并且使用了非常小的堆大小。BufferedReader 一次处理文件 1 行,所以它根本不需要太多内存? (6认同)