内存不足错误,java堆空间

我尝试读取超过400万行和超过400 MB的日志文件,但我得到Out of Memory Error:java堆空间 。 这是我的代码:

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,但仍然得到该消息。 可能的原因是什么?

好的,你已经有了线索,阅读你得到的评论。

问题解释:

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

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

另外, StringBuffer (顺便说一下:更好地使用StringBuilder )在内部再次使用char[] ,它在需要时自动扩展(长度)。 这种扩展是通过加倍长度来完成的。 因此对于400MB文件,它有一个长度为512M的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的某些实例字段中,和/或使此类的行为类似于状态机。