Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching java.lang.OutOfMemoryError?

Documentation for java.lang.Error says:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch

But as java.lang.Error is a subclass of java.lang.Throwable, I can catch this type of Throwable.

I understand why it's not a good idea to catch this sort of exception. As far as I understand, if we decide to catch it, the catch handler should not allocate any memory by itself. Otherwise OutOfMemoryError will be thrown again.

So, my question is:

  1. Are there any real world scenarios when catching java.lang.OutOfMemoryError might be a good idea?
  2. If we decide to catch java.lang.OutOfMemoryError, how can we make sure the catch handler doesn't allocate any memory by itself (any tools or best practices)?
like image 492
Denis Bazhenov Avatar asked Apr 20 '10 23:04

Denis Bazhenov


People also ask

How do I fix Java Lang OutOfMemoryError?

OutOfMemoryError: Java heap space. 1) An easy way to solve OutOfMemoryError in java is to increase the maximum heap size by using JVM options "-Xmx512M", this will immediately solve your OutOfMemoryError.

Can we handle out of memory error in catch block?

As far as I understand, if we decide to catch it, the catch handler should not allocate any memory by itself. Otherwise OutOfMemoryError will be thrown again.

What causes Java Lang OutOfMemoryError?

OutOfMemoryError exception. Usually, this error is thrown when there is insufficient space to allocate an object in the Java heap. In this case, The garbage collector cannot make space available to accommodate a new object, and the heap cannot be expanded further.


1 Answers

There are a number of scenarios where you may wish to catch an OutOfMemoryError and in my experience (on Windows and Solaris JVMs), only very infrequently is OutOfMemoryError the death-knell to a JVM.

There is only one good reason to catch an OutOfMemoryError and that is to close down gracefully, cleanly releasing resources and logging the reason for the failure best you can (if it is still possible to do so).

In general, the OutOfMemoryError occurs due to a block memory allocation that cannot be satisfied with the remaining resources of the heap.

When the Error is thrown the heap contains the same amount of allocated objects as before the unsuccessful allocation and now is the time to drop references to run-time objects to free even more memory that may be required for cleanup. In these cases, it may even be possible to continue but that would definitely be a bad idea as you can never be 100% certain that the JVM is in a reparable state.

Demonstration that OutOfMemoryError does not mean that the JVM is out of memory in the catch block:

private static final int MEGABYTE = (1024*1024); public static void runOutOfMemory() {     MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();     for (int i=1; i <= 100; i++) {         try {             byte[] bytes = new byte[MEGABYTE*500];         } catch (Exception e) {             e.printStackTrace();         } catch (OutOfMemoryError e) {             MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();             long maxMemory = heapUsage.getMax() / MEGABYTE;             long usedMemory = heapUsage.getUsed() / MEGABYTE;             System.out.println(i+ " : Memory Use :" + usedMemory + "M/" +maxMemory+"M");         }     } } 

Output of this code:

1 : Memory Use :0M/247M .. .. .. 98 : Memory Use :0M/247M 99 : Memory Use :0M/247M 100 : Memory Use :0M/247M 

If running something critical, I usually catch the Error, log it to syserr, then log it using my logging framework of choice, then proceed to release resources and close down in a clean fashion. What's the worst that can happen? The JVM is dying (or already dead) anyway and by catching the Error there is at least a chance of cleanup.

The caveat is that you have to target the catching of these types of errors only in places where cleanup is possible. Don't blanket catch(Throwable t) {} everywhere or nonsense like that.

like image 140
Chris Avatar answered Oct 04 '22 11:10

Chris