4 백만 줄 이상, 크기가 400MB 이상인 로그 파일을 읽으려고하는데 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로 늘리려 고했지만 여전히 해당 메시지가 나타납니다. 가능한 원인은 무엇입니까?
좋아, 이미받은 댓글을 읽고 단서가 있어야합니다.
문제 설명 :
로그 파일의 크기는 400MB입니다. 이것은 바이트 단위로 측정됩니다. 이제 한 줄씩 읽고 line = bufferedReader.readLine()
일부 바이트를 문자열로 변환합니다.
String
Java 의 인스턴스는 내부적으로 char[]
. 그러나 char
Java에서는 2 바이트가 필요합니다! 따라서 모든 문자를 저장하려면 최소 800MB의 힙 공간이 필요합니다. 다른 여러 개체도 할당하고 JVM 자체에 약간의 메모리가 필요하므로 1GB로는 충분하지 않을 가능성이 큽니다.
또한 StringBuffer
(그런데 : 더 나은 사용 StringBuilder
) 내부적으로 다시 a를 사용하며 char[]
필요할 때 자동으로 확장됩니다. 이 확장은 길이를 두 배로 늘려 수행됩니다. 따라서 400MB 파일의 경우 char[]
길이가 512M입니다. 여전히 상기 시켜라 : 문자는 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의 일부 인스턴스 필드에 저장하거나이 클래스가 상태 머신처럼 작동하도록해야합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다