What\'s the difference between StackOverflowError and OutOfMemoryError and how to avoid them in application?
From Javadocs: Exceptional conditions associated with JVM Stacks:
1) if insufficient memory can be made available to create the initial JVM stack for a new thread, the JVM throws an OutOfMemoryError.
2) If the computation in a thread requires a larger JVM stack than is permitted, the JVM throws a StackOverflowError.
3) If JVM stack can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, the JVM throws an OutOfMemoryError.
Exceptional conditions associated with Heap:
1) If a computation requires more heap than can be made available by the automatic storage management system, the JVM throws an OutOfMemoryError.
Short answer:
OutOfMemoryError
is related to Heap. StackOverflowError
is related to stackLong answer:
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
& Heap
If you have large objects (or) referenced objects in memory, 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 the required amount of memory.
How to avoid: Make sure un-necessary objects are available for GC
All your local variables and methods calls related data will be on the 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, the stack frame will be removed. ONE WAY to reproduce this is, have an 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 an infinite loop)
The following exceptional conditions are associated with Java Virtual Machine stacks:
If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError.
If Java Virtual Machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java Virtual Machine stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.
The following exceptional condition is associated with the heap:
If a computation requires more heap than can be made available by the automatic storage management system, the Java Virtual Machine throws an OutOfMemoryError.
The following exceptional condition is associated with the method area:
If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an OutOfMemoryError.
The following exceptional condition is associated with the construction of the run-time constant pool for a class or interface:
When creating a class or interface, if the construction of the run-time constant pool requires more memory than can be made available in the method area of the Java Virtual Machine, the Java Virtual Machine throws an OutOfMemoryError.
The following exceptional conditions are associated with native method stacks:
If the computation in a thread requires a larger native method stack than is permitted, the Java Virtual Machine throws a StackOverflowError.
If native method stacks can be dynamically expanded and native method stack expansion is attempted but insufficient memory can be made available, or if insufficient memory can be made available to create the initial native method stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.
https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-2.html
2.5.2. Java Virtual Machine Stacks
2.5.3. Heap
2.5.4. Method Area
2.5.5. Run-Time Constant Pool
2.5.6. Native Method Stacks
2.6. Frames
StackOverflowError : Thrown when a stack overflow occurs because an application recurses too deeply.
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.
In Java Virtual Machine there are several memory area defined :
In all above, you can choose your precision that memory allocated to those memory area will be fixed or will be changed dynamically at runtime.
Now about the question, OutOfMemoryError is applicable for all of the above listed. OutOfMemoryError
will be thrown if memory expansion of any of the memory area will be attempted but enough memory is not available to allocate.
and StackOverFlowError is applicable for Native Method Stack and Java Virtual Machine Stack. StackOverFlowError
will be thrown If the computation in a thread requires a larger stack than is permitted.
For Detailed reference you can read THE STRUCTURE OF THE JAVA VIRTUAL MACHINE
Through the JVM specification, there are 5 data areas.
For JVM Stacks data areas, the spec said the memory size of JVM Stacks can be fixed or dynamically adjustable like the heap area.
When runs out of JVM Stacks memory, there are two cases:
1. If JVM Stacks is implemented as a fixed size, JVM will throw a StackOverflowError.
2. Otherwise, just like the heap area, JVM will throw OutOfMemoryError when failed to allocate more memory.
Any not only for the JVM Stacks area, memory allocations for other data areas will also case OutOfMemoryError due to insufficient memory resources.
For more information, see the JVM specification - Run-Time Data Areas