开发者

Is it such a bad idea to capture OutOfMemoryError? [duplicate]

This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Catching java.lang.OutOfMemoryError

OutOfMemoryError are:

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

Java says:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.

This feels like hearin开发者_运维百科g:

If you are drowning, be reasonable: you should not try to swim upwards to keep your head above water. Death is typically resulting from abnormal conditions.

Let's imagine a scenario where one is running a service. For some reason, another application on the same server is eating a lot of memory, causing an unexpected OOM in your service. Is it such a bad idea to try to reduce this service's memory consumption in order to remain available to user?

Or is there something more fundamental happening at the JVM level preventing the implementation of such a solution after the OOM has been thrown?


As you quoted

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

At that point your are screwed. That description implies that Java/the JVM can't get enough resources to operate, and if that is true, executing more Java code to fix the problem would itself be problematic.

A good analogy is that your car has run out of gas, and you want to fix that by stepping on the accelerator.

A better solution is to do capacity planning and make sure

1) Your servers have enough memory to do their jobs
2) The services running on your servers perform within spec and don't consume more than a certain amount of resources.


The problem here is that by OOM is an error which should not occur under normal circumstances. By catching it and trying to release memory, you are likely obscuring some sort of leak or unintended behaviour elsewhere.

If you do get OOM, perhaps it's because you did not configure the JVM to use more memory.


It is a bad idea. Primarily because OutOfMemoryError is an Error not an Exception - An Error "indicates serious issues that a reasonable application should not try to catch."

Instead, analyse your possible scenarios and apply fixes based on information provided in this PDF


You can't really recover from OOM.

There's one reason however to try and catch anything - that's what the "catch-throwable" faction told me when we did exactly that in a project I no longer work in - that one reason being: try to log what happened. Because if you don't know what happened it is hard to figure out how to get the software back up and running.

There's also a big "but" to that one reason: it won't work usually.

Errors usually can't be fixed from within your running code, that's why there is that difference.


It is useless. Because at the moment the error is catched, you may be so short of heap memory that any new object creation could throw a new OOME. Having such an small margin of maneuver in the catch means that the only action you could take is to exit.

Test this snippet, and tell me what your output is:

      import java.util.LinkedList;
      import java.util.List;

      public class OOMErrorTest {


        public static void main(String[] args) {
            List<Long> ll = new LinkedList<Long>();

            try {
                long l = 0;
                while(true){
                    ll.add(new Long(l++));
                }
            } catch(OutOfMemoryError oome){         
                System.out.println("Error catched!!");
                System.out.println("size:" +ll.size());
            }
            System.out.println("Test finished");
        }

      }

But strictly speaking, yes, these are catchable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜