6

As we all know, there are multiple reasons of OutOfMEmoryError (see first answer). Why there is only one exception covering all these cases instead of multiple fine-grained ones inheriting from OutOfMEmoryError?

UML

Community
  • 1
  • 1
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 1
    Indeed, you are right, but I think by myself: "I've never never never had an `OutOfMemoryError` ..." – Martijn Courteaux Jun 05 '11 at 16:07
  • @Heanel: True, but the question is: is that information provided in the description? – Martijn Courteaux Jun 05 '11 at 16:12
  • 1
    What's the purpose? Can you handle them differently? – Op De Cirkel Jun 05 '11 at 16:18
  • @Op De, the program cannot, but the mortician might benefit from the information. – Thorbjørn Ravn Andersen Jun 05 '11 at 19:18
  • you have forgotten out of direct memory space. but catching OOM will not help at all for many a reason. Some Errors are recoverable but OOMs are practically not, unless you have a single thread. Forgot: tomcat/coyote [where you saw parachute] is riddled w/ dataraces and bad design decisions, incl. CLQ for caching small objects and finalized object on each write, not the best place to steal ideas :) – bestsss Jun 11 '11 at 20:15

6 Answers6

8

I'd expect because you really can't do anything else when that happens: it almost doesn't matter WHY you ran out, since you're screwed regardless. Perhaps the additional info would be nice, but...

I know tomcat tries to do this "Out Of Memory Parachute" thing, where they hold onto a chunk of memory and try and release it, but I'm not sure how well it works.

Femi
  • 64,273
  • 8
  • 118
  • 148
  • That's a good point, but yeah I would still like to have a more descriptive reason for dying on me. :) – Kenny Cason Jun 05 '11 at 16:08
  • Well, its been a while since I had one of those, so I can't remember: do they give you a full stack trace with line numbers? – Femi Jun 05 '11 at 16:11
  • *Out Of Memory Parachute* - could you provide some more information about this feature? Never heard about it... BTW "*[...]JIRA can often recover from the out of memory condition - the long-running processes eventually finish, release their memory and things go back to normal.[...]*" [(source)](https://loft.spartez.com/confluence/display/SPARTEZ/Testing+a+Million+Issue+JIRA+-+The+Verdict) - so `OOME` is not always fatal, especially the "heap" one. – Tomasz Nurkiewicz Jun 05 '11 at 16:18
  • Interesting: didn't know anyone could legitimately recover from an OOME. Take a quick look at http://tomcat.apache.org/tomcat-6.0-doc/config/http.html#Nio_Implementation: search for `oomParachute`. They try to recover from heap OOM errors by holding onto a chunk of memory and then releasing it if an OOME occurs. They explicitly state it only works on OOME with respect to the heap space and there is no guarantee you will be able to recover. – Femi Jun 05 '11 at 17:05
  • @Femi - people try to recover from OOME, but it is rather risky, and can leave you in a worse state than when you started. See the links in my updated answer. – Stephen C Jun 06 '11 at 01:43
  • @Femi, parachute works like that: catch OOM, release 1M (default for tomcat) call GC and try to log. Parachute stuff is basically useless since OOM can happen anywhere when you have tons of threads. The most important part of try to recover from OOM is: sending some alarm to the admin, that's all. It's not recoverable since it can happen *anywhere*, not exactly at the guilty code location. – bestsss Jun 11 '11 at 20:08
7

You only need to subclass an exception if applications need to be able to catch and deal with the different cases differently. But you shouldn't be catching and attempting to recover from these cases at all ... so the need should not arise.

... but yeah I would still like to have a more descriptive reason for dying on me.

The exception message tells you which of the OOME sub-cases have occurred. If you are complaining that the messages are too brief, it is not the role of Java exception messages to give a complete explanation of the problem they are reporting. That's what the javadocs and other documentation is for.


@Thorbjørn presents an equally compelling argument. Basically, the different subcases are all implementation specific. Making them part of the standard API risks constraining JVM implementations to do things in suboptimal ways to satisfy the API requirements. And this approach risks creating unnecessary application portability barriers when new subclasses are created for new implementation specific subcases.

(For instance the hypothetical UnableToCreateNativeThreadError 1) assumes that the thread creation failed because of memory shortage, and 2) that the memory shortage is qualitatively different from a normal out of memory. 2) is true for current Oracle JVMs, but not for all JVMs. 1) is possibly not even true for current Oracle JVMs. Thread creation could fail because of an OS-imposed limit on the number of native threads.)


If you are interested in why it is a bad idea to try to recover from OOME's, see these Questions:

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    In that case we would not need any subclasses of Error at all. – Duncan McGregor Jun 05 '11 at 16:12
  • Yes, you could make that argument. Except that some code really *does* need to handle some Error subclasses. OOME is an example that it is particularly unsafe to attempt to handle ... apart from to report the error. – Stephen C Jun 05 '11 at 16:20
  • I agree with your subclass vs. message explanation. However (look at *Femi* answer and comments) there are some rare cases where an application tries to handle only heap-related OOME and can either treat all OOME as *out of heap* or parse error message, which is a very bad practice. So I would expect at least `OutOfHeapSpaceError` to be existing. – Tomasz Nurkiewicz Jun 11 '11 at 12:07
  • 1
    @Duncan, this is not true LinkageErrors are easy to recover any time you wish, OOM can happen w/o a sign in the best behaved thread since all the threads (execution paths) do compete for the same resource. Stackoverflow is recoverable (catching in the threadgroup or unhandled exception handler), shutting the thread down, redploying the faulty code and move on (send alarm to admin, etc) – bestsss Jun 11 '11 at 20:10
  • @Tomasz - it is a bad idea to design the standard APIs to support dangerous things such as OOME recovery. If that then means that people have to parse exception messages to do those dangerous things ... that's OK, as far as I'm concerned. – Stephen C Jun 12 '11 at 01:36
7

The garbage collection process is deliberately very vaguely described to allow the greatest possible freedom for the JVM-implementors.

Hence the classes you mention are not provided in the API, but only in the implementation.

If you relied on them, your program would crash if running on a JVM without these vendor-specific sub-classes, so you don't do that.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • 1
    Good point about GC implementation freedom. We would probably end up with exception in `sun` or `com.sun` packages to describe Sun-specific error conditions. – Tomasz Nurkiewicz Jun 11 '11 at 12:08
  • 1
    My reading of the JVM specification is that it allows the JVM to throw a sub class of `OutOfMemoryError`; note that `OutOfMemoryError` is not `final`. So the JVM implementor *might* throw a system-dependent sub class of `OutOfMemoryError`. – Raedwald Jan 10 '12 at 13:25
  • @Raedwald naturally. I was discussing the case of you referring to such a subclass in your own code. – Thorbjørn Ravn Andersen Jan 10 '12 at 16:02
  • Yes. In theory, the documentation of a JVM might declare that it threw specific sub classes of `OutOfMemoryError`, and the programmer might then be (foolishly) tempted to try to catch them. – Raedwald Jan 10 '12 at 19:07
2

IMO there is no definite answer to this question and it all boils down to the design decisions made at that time. This question is very similar to something like "why isn't Date class immutable" or "why does Properties extend from HashTable". As pointed out by another poster, subclasses really wouldn't matter since you are anyways screwed. Plus the descriptive error messages are good enough to start with troubleshooting measures.

Sanjay T. Sharma
  • 22,857
  • 4
  • 59
  • 71
1

this is because all 4 are fatal errors that impossible to recover from (except perhaps out of heap space but that would still remain near the edge of the failure point)

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
ratchet freak
  • 47,288
  • 5
  • 68
  • 106
1

Mostly because computing something smart will require to allocate memory at some point. So you have to trhrow OutOfMemoryException without doing anymore computation.

This is not a big deal anyway, because your program is already screwed up. At most what you can do is return an error to the system System.exit(ERROR_LEVEL); but you can't even log because it would require to allocate memory or use memory that is possibly screwed up.

deadalnix
  • 2,255
  • 18
  • 24