Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java out of memory errors

Why does this following code

List<Object> list = new ArrayList<>();
while (true) {
    for(int i = 0; i < 1000000; i++){
        list.add(new Object());
    }
}

produce an out of memory error

But this code doesn't

while(true) {
    List<Object> list = new ArrayList<>();
    for(int i = 0; i < 1000000; i++){
        list.add(new Object());
    }
}

I can see that it has something to do with the list being created either inside the while loop or outside of it obviously, but I am unsure on the reason why this happens.

like image 261
Donald Avatar asked Jun 14 '17 05:06

Donald


People also ask

What causes Java out of memory error?

OutOfMemoryError exception. Usually, this error is thrown when there is insufficient space to allocate an object in the Java heap. In this case, The garbage collector cannot make space available to accommodate a new object, and the heap cannot be expanded further.

How do I resolve out of memory error in production?

The first approach is to try and reproduce the memory leak in a dev or test environment using tools like a profiler, which will step through code execution and show the state of memory, heap, and object allocation as you hit the application with requests.

What causes out of memory errors?

An "Out of Memory" error can occur when a Database Node Memory (KB) becomes less than 2 percent of the target size, and it cannot discard database pages on the node anymore to get free pages.


2 Answers

In the first case, you have a single ArrayList instance and you keep adding to it new Object instances until you run out of memory.

In the second case, you create a new ArrayList in each iteration of the while loop and add 1000000 Object instances to it, which means the ArrayList created in the previous iteration and the 1000000 Object instances it contains can be garbage collected, since the program no longer has references to them.

Note that the second snippet can also cause out of memory error if the new Objects are created faster than the garbage collector can release the old ones, but that depends on the JVM implementation.

like image 69
Eran Avatar answered Oct 02 '22 11:10

Eran


In the first snippet, the list is created (and retained!) outside the loop, so you just keep endlessly adding elements to it until you consume all the available memory.

In the second snippet, each iteration of the while loop creates a new ArrayList object. Since you no longer hold a reference to that instance once the iteration ends, this list is eligible for garbage collection, so the old lists keep getting freed and you don't exhaust your memory.

like image 23
Mureinik Avatar answered Oct 02 '22 11:10

Mureinik