How do I make the JVM exit on ANY OutOfMemoryException even when bad people try to catch it

后端 未结 10 505
醉梦人生
醉梦人生 2020-12-09 16:32

An OOME is of the class of errors which generally you shouldn\'t recover from. But if it is buried in a thread, or someone catches it, it is possible for an application to g

相关标签:
10条回答
  • 2020-12-09 17:04

    User @dennie posted a comment which should really be its own answer. Newer JVM features make this easy, specifically

    -XX:+ExitOnOutOfMemoryError
    

    to exit on OOME, or to crash:

    -XX:+CrashOnOutOfMemoryError
    

    Since Java 8u92 https://www.oracle.com/java/technologies/javase/8u92-relnotes.html

    0 讨论(0)
  • 2020-12-09 17:08

    How about catching OOME yourself in your code and System.exit()?

    0 讨论(0)
  • 2020-12-09 17:09

    If some piece of code in your application's JVM decides that it wants to try to catch OOMEs and attempt to recover, there is (unfortunately) nothing you that you can do to stop it ... apart from AOP heroics that are probably impractical, and definitely are bad for your application's performance and maintainability. Apart from that, the best you can do is to pull the plug on the JVM using an "OnOutOfMemoryError" hook. See the answer above: https://stackoverflow.com/a/3878199/139985/

    Basically, you have to trust other developers not to do stupid things. Other stupid things that you probably shouldn't try to defend against include:

    • calling System.exit() deep in a library method,
    • calling Thread.stop() and friends,
    • leaking open streams, database connections and so on,
    • spawning lots of threads,
    • randomly squashing (i.e. catching and ignoring) exception,
    • etc.

    In practice, the way to pick up problems like this in code written by other people is to use code quality checkers, and perform code reviews.

    If the problem is in 3rd-party code, report it as a BUG (which it probably is) and if they disagree, start looking for alternatives.


    For those who don't already know this, there are a number of reason why it is a bad idea to try to recover from an OOME:

    1. The OOME might have been thrown while the current thread was in the middle of updating some important data structure. In the general case, the code that catches this OOME has no way of knowing this, and if it tries to "recover" there is a risk that the application will continue with a damages data structure.

    2. If the application is multi-threaded there is a chance that OOMEs might have been thrown on other threads as well, making recovery even harder.

    3. Even if the application can recover without leaving data structures in an inconsistent state, the recovery may just cause the application to limp along for a few seconds more and then OOME again.

    4. Unless you set the JVM options appropriately, a JVM that has almost run out of memory tends to spend a lot of time garbage collecting in a vain attempt to keep doing. Attempting to recover from OOMEs is likely to prolong the agony.

    Recovering from an OOME does nothing to address the root cause which is typically, a memory leak, a poorly designed (i.e. memory wasteful) data structure, and/or launching the application with a heap that is too small.

    0 讨论(0)
  • 2020-12-09 17:12

    You can run your java program using Java Service Wrapper with an OutOfMemory Detection Filter. However, this assumes that the "bad people" are nice enough to log the error :)

    0 讨论(0)
提交回复
热议问题