内存不足错误,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堆空间的主要内容,如果未能解决你的问题,请参考以下文章
内存不足:Java 堆空间,但在查看堆空间时最大使用 50 MB