Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

out of memory error, java heap space

I try to read log file with more than 4 million lines and size more than 400 MB, but I get Out of Memory Error : java heap space. This is my code :

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);
        }

I tried to increase heap memory to 1GB, but still get that message. What would be the possible cause?

like image 894
Arief Taufikurrahman Avatar asked Dec 17 '13 05:12

Arief Taufikurrahman


People also ask

What does Java heap space OutOfMemoryError mean?

In this example, an Integer array with a very large size is attempted to be initialized. Because the Java heap is insufficient to allocate this array, it throws a java.lang.OutOfMemoryError: Java heap space.

How do I fix Java heap space?

If you get an OutOfMemoryError with the message “ Java heap space ” (not to be confused with message “ PermGen space “), it simply means the JVM ran out of memory. When it occurs, you basically have 2 options: Solution 1. Allow the JVM to use more memory With the -Xmx JVM argument, you can set the heap size.

What is an out of memory error in Java?

The name of the error itself conveys that it is an out-of-memory error where the JVM throws such error when it cannot allocate an object in the heap memory. So, in this section, we are going to discuss the Java.lang.outofmemory error, about heap space, and how to fix the error.

How does heap memory affect the size of an object?

The amount of heap memory used by a Java application impacts the number of objects that can be allocated and their size. If an object requires more memory than is available in the heap, the application can encounter a java.lang.OutOfMemoryError.


1 Answers

Ok, you already should have a clue, reading the comments you got.

Problem explanation:

Your log file has a size of 400MB. Note, that this is measured in bytes. Now you are reading it line by line with line = bufferedReader.readLine() thus converting some bytes to a string.

A String instance in Java internally holds a char[]. But a char in Java takes 2 bytes! So you need at least 800MB of heap space just for storing all the characters. As you are also allocating several other objects, and the JVM itself needs some memory, it is very probable that 1 GB is not enough.

Additionally, the StringBuffer (by the way: better use StringBuilder for that) internally uses again a char[], which is expanded (in length) automatically when needed. This expansion is done by doubling the length. So for a 400MB file it has a char[] with a length of 512M. Still remind: A char takes 2 bytes.

So what is the solution? Simply put: Do not read the entire file into memory!

Do that instead:

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
    }
}

If you need to keep some lines, you should store them in some instance fields of the LogAnalyzer, and/or have this class behave like a state machine.

like image 95
Seelenvirtuose Avatar answered Sep 25 '22 02:09

Seelenvirtuose