Documentation for java.lang.Error
says:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application
You can recover from it:
package com.stackoverflow.q2679330;
public class Test {
public static void main(String... args) {
int size = Integer.MAX_VALUE;
int factor = 10;
while (true) {
try {
System.out.println("Trying to allocate " + size + " bytes");
byte[] bytes = new byte[size];
System.out.println("Succeed!");
break;
} catch (OutOfMemoryError e) {
System.out.println("OOME .. Trying again with 10x less");
size /= factor;
}
}
}
}
But does it make sense? What else would you like to do? Why would you initially allocate that much of memory? Is less memory also OK? Why don't you already make use of it anyway? Or if that's not possible, why not just giving the JVM more memory from the beginning on?
Back to your questions:
1: is there any real word scenarios when catching java.lang.OutOfMemoryError may be a good idea?
None comes to mind.
2: if we catching java.lang.OutOfMemoryError how can we sure that catch handler doesn't allocate any memory by itself (any tools or best practicies)?
Depends on what has caused the OOME. If it's declared outside the try
block and it happened step-by-step, then your chances are little. You may want to reserve some memory space beforehand:
private static byte[] reserve = new byte[1024 * 1024]; // Reserves 1MB.
and then set it to zero during OOME:
} catch (OutOfMemoryException e) {
reserve = new byte[0];
// Ha! 1MB free!
}
Of course this makes all with all no sense ;) Just give JVM sufficient memory as your applictation require. Run a profiler if necessary.