OutOfMemoryError and StackOverflowError

I have been confused of OutOfMemoryError and StackOverflowError, not being able to distinguish differences between them. So here comes this post.

OutOfMemoryError

https://docs.oracle.com/javase/8/docs/api/java/lang/OutOfMemoryError.html

1
2
3
4
5
java.lang.Object
- java.lang.Throwable
- java.lang.Error
- java.lang.VirtualMachineError
- java.lang.OutOfMemoryError

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. OutOfMemoryError objects may be constructed by the virtual machine as if suppression were disabled and/or the stack trace was not writable.

StackOverflowError

https://docs.oracle.com/javase/8/docs/api/java/lang/StackOverflowError.html

1
2
3
4
5
java.lang.Object
- java.lang.Throwable
- java.lang.Error
- java.lang.VirtualMachineError
- java.lang.StackOverflowError

Thrown when a stack overflow occurs because an application recurses too deeply.

Error, Exception, and RuntimeException - The First Observation

1
2
3
4
5
- java.lang.Object
- java.lang.Throwable
- java.lang.Error
- java.lang.Exception
- java.lang.RuntimeException

The first observation is that these are of Error, not Exception or RuntimeException. As you can see from the above hierarchy, Error, Exception, and RuntimeException are three equative classes.

According to https://docs.oracle.com/javase/8/docs/api/java/lang/Error.html

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a “normal” condition, is also a subclass of Error because most applications should not try to catch it.

A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur. That is, Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions.

So, Error should not be explicitly caught and handled by your application.

Ok, good to get clarified we are not talking about Exception or RuntimeException.

Here’s another of my posts talking specifically for Java Exception https://phoenixjiangnan.github.io/2016/07/04/java/exception/Java%20-%20Exception%20-%20Principles%20to%20Handle%20Exception/

Let’s get focused on Error.

OutOfMemoryError v.s. StackOverflowError

When you start JVM you define how much RAM it can use for processing. JVM divides this into certain memory locations for its processing purpose, two of those are Stack and Heap.

Heap and OutOfMemoryError

OutOfMemoryError is related to Heap.

If you have large objects (or) referenced objects in memeory, then you will see OutofMemoryError. If you have strong references to objects, then GC can’t clean the memory space allocated for that object. When JVM tries to allocate memory for new object and not enough space available it throws OutofMemoryError because it can’t allocate required amount of memory.

How to avoid: Make sure un-necessary objects are available for GC

Stack and StackOverflowError

StackOverflowError is related to stack.

All your local variables and methods calls related data will be on stack. For every method call, one stack frame will be created and local as well as method call related data will be placed inside the stack frame. Once method execution is completed, stack frame will be removed. ONE WAY to reproduce this is, have infinite loop for method call, you will see stackoverflow error, because stack frame will be populated with method data for every call but it won’t be freed (removed).

How to avoid Make sure method calls are ending (not in infinite loop)

Java Stack vs Heap

Java Heap Space

Java Heap space is used by java runtime to allocate memory to Objects and JRE classes.

Whenever we create an object, it’s always created in the Heap space. Garbage Collection runs on the heap memory to free the memory used by objects that doesn’t have any reference. Any object created in the heap space has global access and can be referenced from anywhere of the application.

Java Stack Memory

Java Stack memory is used for execution of a thread. They contain method specific values that are short-lived and references to other objects in the heap that are getting referred from the method.

Stack memory is always referenced in LIFO (Last-In-First-Out) order. Whenever a method is invoked, a new block is created in the stack memory for the method to hold local primitive values and reference to other objects in the method. As soon as method ends, the block becomes unused and become available for next method.
Stack memory size is very less compared to Heap memory.

Summary

Did you get the differences between those two errors? I did!