How to Handle Outofmemoryerror

How to deal with java.lang.OutOfMemoryError: Java heap space error?

Ultimately you always have a finite max of heap to use no matter what platform you are running on. In Windows 32 bit this is around 2GB (not specifically heap but total amount of memory per process). It just happens that Java chooses to make the default smaller (presumably so that the programmer can't create programs that have runaway memory allocation without running into this problem and having to examine exactly what they are doing).

So this given there are several approaches you could take to either determine what amount of memory you need or to reduce the amount of memory you are using. One common mistake with garbage collected languages such as Java or C# is to keep around references to objects that you no longer are using, or allocating many objects when you could reuse them instead. As long as objects have a reference to them they will continue to use heap space as the garbage collector will not delete them.

In this case you can use a Java memory profiler to determine what methods in your program are allocating large number of objects and then determine if there is a way to make sure they are no longer referenced, or to not allocate them in the first place. One option which I have used in the past is "JMP" http://www.khelekore.org/jmp/.

If you determine that you are allocating these objects for a reason and you need to keep around references (depending on what you are doing this might be the case), you will just need to increase the max heap size when you start the program. However, once you do the memory profiling and understand how your objects are getting allocated you should have a better idea about how much memory you need.

In general if you can't guarantee that your program will run in some finite amount of memory (perhaps depending on input size) you will always run into this problem. Only after exhausting all of this will you need to look into caching objects out to disk etc. At this point you should have a very good reason to say "I need Xgb of memory" for something and you can't work around it by improving your algorithms or memory allocation patterns. Generally this will only usually be the case for algorithms operating on large datasets (like a database or some scientific analysis program) and then techniques like caching and memory mapped IO become useful.

Catching java.lang.OutOfMemoryError?

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.

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

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.

How to handle OutOfMemoryError

Check that the image size is smaller than the available memory before attempting to load it. So the most efficient way to handle OutOfMemoryException is to architecture your application in such a way that it never attempts to load lots of data into memory in order to avoid the exception.

Out of memory error java.lang.OutOfMemoryError

So it's a user crash. You are out of luck then. So you have a user with a cheap device that can't handle that image. :)

The best I can suggest:

  • Create a downscaled version of the image
  • Do a try/catch in ActivityWorkout.onCreate
  • Capture the out-of-memory exception
  • Set a "this is a low-memory device" flag in the settings (use SharedPreferences)
  • Before loading the layout, read that flag
  • Depending on its value, conditionally use either the full, or the downscaled version of the image

How to handle java.lang.OutOfMemoryError

  • You can set java heap space from command line: java -Xmx1600m program Now your heap space is 1600 MB.(Assuming your hardware can already afford 1600MB.)

  • For Windows platforms, you can set it from Java Runtime Environment
    Settings
    as well. Follow Control Panel => Programs => Java. Navigate to Java tab. View Java Runtime Environment Settings. Add -Xmx1600m to Runtime Parameters. Save and go on.

  • For Linux platforms, you can launch Control Panel and edit runtime parameters. It can be run from something like /usr/j2se/jre/bin/ControlPanel. Find your own directory. Read here please: http://docs.oracle.com/javase/7/docs/technotes/guides/deployment/deployment-guide/jcp.html



Related Topics



Leave a reply



Submit