Pawel Veselov said the following on 07/15/10 10:08:
Florian Weimer said the following on 07/14/10 23:25:
* Pawel Veselov:
The fact that I catch any Throwable around the code that threw the
OOM error didn't particularly help. The error was logged, but the
timer thread still died.
By definition, a VM which throws an Error (or even
VirtualMachineError) is unstable and needs to be restarted. The
description of VirtualMachineError makes that pretty clear. You
cannot even know that the thread that triggers such exceptions is
responsible for their actual cause.
An OutOfMemoryError for the Java heap does not fall into that category. OOM
is a transient failure in many circumstances.
Not to be a nag here, but VirtualMachineError javadoc says "Thrown to
indicate that the Java Virtual Machine is broken or has run out of
resources necessary for it *to continue operating*.", and
OutOfMemoryError extends VME.
I think it is a historical mistake that OOME is a subclass of VME, as
least so far as the non-recoverability in the Java-heap is concerned. I
would suggest (somewhat tongue-in-cheek) that it was done at a time when
people were far more familiar with OOM being a fatal error in C, than
with it being a transient condition in a GC'd language. That said there
should have been different OOME types for the Java heap and native-heap
exhaustion (the latter of which is typically so fatal you don't even get
the OOME thrown).
It is true that it is a transient
failure in many circumstances, but if its impossible to find out, for
an application, what the circumstances and implications are, along
with whether these errors are even being thrown around, what should
the application do?
Serious applications that get OOME for heap exhaustion typically attempt:
- retry (GC could be in progress)
- request explicit GC
- request explicit finalization
- free up other memory used by the application (eg purge data structures)
- some combination of the above
Cheers,
David Holmes