Is the garbage collector guaranteed to run before Out of Memory Error?
In case the heap is full, the JVM throws an
OutOfMemoryError
. But is it assured that a (full) garbage collection always takes place before such an exception is thrown?
This would mean that the memory is full only with strong referenced objects (or reachable by GC Roots) when the exception is thrown.
Edit: Assume the Sun JVM - HotSpot is in discussion.
Solution 1:
The Java Machine Specification states in section 6.3 (emphasis mine):
OutOfMemoryError
: The Java virtual machine implementation has run out of either virtual or physical memory, and the automatic storage manager was unable to reclaim enough memory to satisfy an object creation request.
So the JVM does give a guarantee that it will try what it can to free up memory through garbage collection before it throws an OOME.
Solution 2:
The garbage collector will usually be run before an OutOfMemoryError is thrown. However you might get an OOME without a GC if you
- try to create a very large object (e.g. larger than the heap)
- start a thread and there is not enough virtual memory or resources to start the thread.
- older versions of Java would throw this error if you reached your maximum direct memory.
Solution 3:
You are not guaranteed that a full garbage collection has been performed, but that the VM has tried to make enough memory available through garbage collection. You could have found that in the API documentation for the OutOfMemoryError class:
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.
Note that there are cases where the garbage collector can decide that enough memory is not available without actually trying to discard unreferenced object instances. The most obvious example is if you try to allocate more memory in one go (e.g. a large byte array) than the max heap size. In this case, an OutOfMemoryError may be thrown without the garbage collector being run at all.
Solution 4:
There's no guaranty that the last operation preceding OutOfMemoryError
is garbage collection. Most probably not, since garbage collection would reduce the amount of used memory not increase it.