Is it possible to catch out of memory exception in java? [duplicate]

It's not an exception; it's an error: java.lang.OutOfMemoryError

You can catch it as it descends from Throwable:

try {
    // create lots of objects here and stash them somewhere
} catch (OutOfMemoryError E) {
    // release some (all) of the above objects
}

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.


It's possible:

try {
   // tragic logic created OOME, but we can blame it on lack of memory
} catch(OutOfMemoryError e) {
   // but what the hell will you do here :)
} finally {
   // get ready to be fired by your boss
}

You can catch and attempt to recover from OutOfMemoryError (OOM) exceptions, BUT IT IS PROBABLY A BAD IDEA ... especially if your aim is for the application to "keep going".

There are a number of reasons for this:

  1. As others have pointed out, there are better ways to manage memory resources than explicitly freeing things; i.e. using SoftReference and WeakReference for objects that could be freed if memory is short.

  2. If you wait until you actually run out of memory before freeing things, your application is likely to spend more time running the garbage collector. Depending on your JVM version and on your GC tuning parameters, the JVM can end up running the GC more and more frequently as it approaches the point at which will throw an OOM. The slowdown (in terms of the application doing useful work) can be significant. You probably want to avoid this.

  3. If the root cause of your problem is a memory leak, then the chances are that catching and recovering from the OOM will not reclaim the leaked memory. You application will keep going for a bit then OOM again, and again, and again at ever reducing intervals.

So my advice is NOT attempt to keep going from an OOM ... unless you know:

  • where and why the OOM happened,
  • that there won't have been any "collateral damage", and
  • that your recovery will release enough memory to continue.

just throwing this out there for all those who ponder why someone might be running out of memory: i'm working on a project that runs out of memory frequently and i have had to implement a solution for this.

the project is a component of a forensics and investigation app. after collecting data in the field (using very low memory footprint, btw) data is opened in our investigation app. one of the features is to perform a CFG traversal of any arbitrary binary image that was captured in the field (applications from physical memory). these traversals can take a long time, but produce very helpful visual representations of the binary that was traversed.

to speed the traversal process, we try to keep as much data in physical memory as possible, but the data structures grow as the binary grows and we cannot keep it ALL in memory (the goal is to use a java heap less than 256m). so what do i do?

i created disk-backed versions of LinkedLists, Hashtables, etc. these are drop-in replacements for their counterparts and implement all the same interfaces so they look identical from the outside world.

the difference? these replacement structures cooperate with each other, catching out of memory errors and requesting that the least recently used elements from the least recently used collection be freed from memory. freeing the element dumps it to disk in temporary file (in the system provided temp directory) and marks a placeholder objects as "paged-out" in the proper collection.

there are PLENTY of reasons you might run out of memory in a java app - the root of most of these reasons is either one or both of: 1. App runs on a resource constrained machine (or attempts to limit resource usage by limiting heap size) 2. App simply requires large amounts of memory (image editing was suggested, but how about audio and video? what about compilers like in my case? how about long-term data collectors without non-volatile storage?)

-bit


It is possible to catch an OutOfMemoryError (It's an Error, not an Exception), but you should be aware, that there is no way to get a defined behaviour.
You may even get another OutOfMemoryError while trying to catch it.

So the better way is to create/use memory aware Caches. There are some frameworks out there (example: JCS), but you can easily build your own by using SoftReference. There is a small article about how to use it here. Follow the links in the article to get more informations.