Is there any point catching an out of memory error (java.lang.OutOfMemoryError
) in Java?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
This is one of the errors you should never catch. The reason for this is simple you will not be able to do anything about it at runtime. However if your application is regularly facing this error then you should consider the following strategies to mitigate this issue-
If the errors still persist then use a profiler like JProfiler or a Eclipse MAT to analyze how much memory your application uses.
Move to a 64 bit system and increase the JVM memory even further.
It's not an exception; it's an error: java.lang.OutOfMemoryError
You can catch it as it descends from Throwable:
However, unless you're doing some rather specific stuff (allocating tons of things within a specific code section, for example) you likely won't be able to catch it as you won't know where it's going to be thrown from.
As some other answers have pointed out, it is a bad idea to catch
OutOfMemoryError
and attempt to recover1. Rather than just repeating that the javadoc says youError
exceptions are not recoverable, I'll try to explain why.In fact there are at least two solid reasons why OOME recovery is unwise:
The First Reason is that OOME's are typically the result of undiagnosed memory leaks. If your application catches and attempts to recover, the chances are that the leaked memory will still be reachable and hence still won't be reclaimed. So when your application starts doing things it is likely to leak more memory ... and run into another OOME. Sooner or later, the application grinds to a halt.
Since there is no way you can be absolutely sure that your application doesn't leak, OOME recovery is never going to be a solid, reliable answer.
The Second Reason is that when an OOME occurs, there is a chance that it will do damage to the execution state. It might cause threads to terminate, leaving other threads waiting for notifications that will never arrive, etc. It might occur in the middle of updating a critical application data structure or (possibly worse) a JVM data structure. If your application then attempts to recover, it might lock up, or (worse) it might manage to keep going with corrupted data, and produce unpredictable results.
Unless you perform a forensic analysis of your codebase, you can never be entirely sure that this kind of thing won't happen.
I won't say you should NEVER attempt to recover from an OOME, but in general it is a risky thing to do. And the more complex your application is, the harder it is to evaluate the risk.
1 - Here I am talking about catching OOME in an attempt to allow the application to continue running as before; i.e. to recover the application. Catching an OOME in order to perform (or trigger) an orderly shutdown is a different matter.
The only place I have done that was mobile development. You can ask user to close other applications in order to give your application ability to work properly. But that's not the case of Android development.
I don't see any other things you can do with the situation. May be, some appropriate logging or cleanup.
Yes. Here are a few examples where it could make sense:
However, note that normally (unless you're at a spot where you'll be allocating tons of memory at once), you probably wouldn't specifically catch OutOfMemoryError for these cases, but rather do a
catch Throwable
all the way at the top in your main entry point.This has already been mentioned a number of times, but the replies indicate a few people are confused about this (common) recovery technique for an
OutOfMemoryError
. Check my post to What if new fails? for a demo of how to do it.