内存不足错误,java堆空间

Posted

技术标签:

【中文标题】内存不足错误,java堆空间【英文标题】:out of memory error, java heap space 【发布时间】: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 显然。 【参考方案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 的某些实例字段中,和/或让此类表现得像一个状态机。

【讨论】:

以上是关于内存不足错误,java堆空间的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse 堆空间(内存不足错误)

理解 JVM 内存分配和 Java 内存不足:堆空间

Hive - 内存不足异常 - Java 堆空间

内存不足:Java 堆空间,但在查看堆空间时最大使用 50 MB

内存不足错误:Android Studio 上的 Java 堆内存

sparklyr中的堆空间不足,但有足够的内存