6
votes

My Java program threw an OutOfMemoryError. How do I debug and fix this problem?


Many newcomers to Java struggle to cope with an OutOfMemoryError. This is an attempt to create a canonical question that will answer the most frequently asked questions about an OutOfMemoryError. I'm creating this new question, rather than adapting one of the numerous previous questions about a OutOfMemoryError because those questions and their answers are tightly coupled to the particular problem a person had.

This question is distinct from general advice on debugging exceptions because the cause of the problem is not always on the call stack, and specific advice is necessary.

4
Downvotes. Interesting. As if some people do not want to create a canonical question.Raedwald
I'm sure people want a canonical question, just not your canonical question. :-P (I'm not one of the downvoters.)Chris Jester-Young
There are already about a dozen questions on this site about how to deal with an OutOfMemoryError in Java. How does adding one more help anyone?Dawood ibn Kareem
@DavidWallace The intent of a "canonical" question is to make all the other similar question marked duplicate of the canonical one. Again, though, my comment is, why pick this one over any of the others?Chris Jester-Young
They're all already mostly duplicates of each other. Adding one more doesn't fix anything.Dawood ibn Kareem

4 Answers

11
votes

An OutOfMemoryError is an exception thrown by the Java Virtual Machine (JVM) because it needs to allocate memory for a (new) object, but insufficient memory is available for the object. The JVM will have first tried to free memory used by dead objects, by running the garbage collector.

As an OutOfMemoryError is a VirtualMachineError, the JVM is permitted to throw it at any time, although it must try to release memory through garbage collection first.

However, in practice it is likely to be thrown from a new statement that tried to create an object for which memory could not be allocated. Therefore, you should first examine the stacktrace associated with the exception for clues about the cause of the problem, as you would for any other exception.

  • If the exception is thrown from an attempt to allocate an array (such as int[] values = new int[n]), the cause could be that you are trying to create an excessively large array (n is too large). Have you made a mistake in the calculation of the size of array you need?
  • If the exception is thrown from an attempt to allocate an array in a method of a container class written by someone else, the cause could be that your code is asking the container to store an excessive number of things. Methods such as ArrayList.reserve(int) and HashMap(int) must allocate storage for future use. Have you made a mistake in the calculation of the size of container you need?
  • If the exception is thrown from inside a loop, the cause could be that the code has looped too many times. Is your loop termination condition correct? If it is a for loop, are you asking it to loop the correct number of times?

If the stacktrace does not provide enough clues, you could try using a heap profiler. That is a monitoring program that enables you to examine the memory used for objects while the program runs, or examies a heap dump written when the program exits. It can provide information about the sizes, number and classes of objects stored in memory.

The JVM has a finite amount of memory made available to it. You might conclude that you program is behaving correctly, but just needs more memory to run than has been made available to it. If you do not explicitly tell the JVM how much memory to use, most implementations will choose a sensible default amount based on the amount of RAM that your computer has, but that amount could be too small for your program. Command line options for the JVM can control how much memory is made available. For most JVM implementations, the most important of those options are -Xmx and -Xms.

8
votes

To debug an OutOfMemoryError, invoke the JVM with the -XX:+HeapDumpOnOutOfMemoryError option, which will cause a heap dump to be written out when an OutOfMemoryError occurs. Then use a tool like VisualVM, jhat, or fasthat to look at the heap dump.

You can also generate a heap dump manually at any time by using jmap with the -dump option.

Disclosure: I'm the maintainer of fasthat, which is a fork of jhat.

0
votes

When the application resources run out of the allocated memory of JVM heap, the OutOfMemmoryException is thrown. Try increasing JVM heap size.

0
votes

This problem occur when tomcat goes out of memory i.e tomcat has less memory configured then the application required to run application.

So to overcome this problem go to the tomcat bin directory and create a new file setenv.bat and define PermSize in that file as below:

set JAVA_OPTS=-Dfile.encoding=UTF-8 -Xms512m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m

PermSize can be set to more higher range according to the application requirement.