【问题标题】:out of memory error, java heap space内存不足错误,java堆空间
【发布时间】:2014-01-04 18:32:13
【问题描述】:

我尝试读取超过 400 万行且大小超过 400 MB 的日志文件,但我得到 Out of Memory Error : java heap space。这是我的代码:

File file = new File("C:\\file.log");
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        StringBuilder stringBuffer = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuffer.append(line);
        }

我尝试将堆内存增加到 1GB,但仍然收到该消息。可能的原因是什么?

【问题讨论】:

  • 不要将整个文件存储在 StringBuffer 中...您要对文件内容做什么?
  • @ElliottFrisch 如果他增加到 1GB 并且文件只有 400MB - 它还会失败吗?
  • @ElliottFrisch :我尝试用特定参数拆分它
  • 用什么参数分割。分裂的部分怎么办?
  • @user2310289 显然。

标签: java heap-memory


【解决方案1】:

好的,你应该已经有了线索,阅读你得到的 cmets。

问题说明:

您的日志文件大小为 400MB。请注意,这是以字节为单位的。现在您正在使用line = bufferedReader.readLine() 逐行读取它,从而将一些字节转换为字符串。

Java 中的String 实例内部包含char[]。但是 Java 中的 char 需要 2 个字节!因此,您至少需要 800MB 的堆空间来存储所有字符。由于您还分配了几个其他对象,并且 JVM 本身需要一些内存,因此 1 GB 很可能是不够的。

此外,StringBuffer(顺便说一句:最好使用StringBuilder)在内部再次使用char[],它会在需要时自动扩展(长度)。这种扩展是通过将长度加倍来完成的。所以对于一个 400MB 的文件,它有一个长度为 512M 的char[]。还是提醒一下:一个char需要2个字节。

那么解决方法是什么?简单地说:不要将整个文件读入内存!

改为这样做:

class LogAnalyzer {
    private final File logFile;

    LogAnalyzer(File logFile) {
        this.logFile = logFile;
    }

    void analyze() throws IOException {
        try(FileReader fileReader = new FileReader(logFile)) {
            try(BufferedReader bufferedReader = new BufferedReader(fileReader)) {
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    analyzeLine(line);
                }
            }
        }
    }

    private void analyzeLine(String line) {
        // do whatever you need here
    }
}

如果您需要保留一些行,您应该将它们存储在 LogAnalyzer 的某些实例字段中,和/或让此类表现得像一个状态机。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    相关资源
    最近更新 更多