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

1,722,541

Solution 1

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.

Solution 2

Run Java with the command-line option -Xmx, which sets the maximum size of the heap.

See here for details.

Solution 3

You could specify per project how much heap space your project wants

Following is for Eclipse Helios/Juno/Kepler:

Right mouse click on

 Run As - Run Configuration - Arguments - Vm Arguments, 

then add this

-Xmx2048m

Solution 4

Increasing the heap size is not a "fix" it is a "plaster", 100% temporary. It will crash again in somewhere else. To avoid these issues, write high performance code.

  1. Use local variables wherever possible.
  2. Make sure you select the correct object (EX: Selection between String, StringBuffer and StringBuilder)
  3. Use a good code system for your program(EX: Using static variables VS non static variables)
  4. Other stuff which could work on your code.
  5. Try to move with multy THREADING

Solution 5

Big caveat ---- at my office, we were finding that (on some windows machines) we could not allocate more than 512m for Java heap. This turned out to be due to the Kaspersky anti-virus product installed on some of those machines. After uninstalling that AV product, we found we could allocate at least 1.6gb, i.e, -Xmx1600m (m is mandatory other wise it will lead to another error "Too small initial heap") works.

No idea if this happens with other AV products but presumably this is happening because the AV program is reserving a small block of memory in every address space, thereby preventing a single really large allocation.

Share:
1,722,541
Eugene Yokota
Author by

Eugene Yokota

Hi, I'm Eugene (eed3si9n). I am a software engineer and an open source contributor mostly around Scala. As the core maintainer of sbt, a build tool used in Scala community, I like helping debug and explain sbt. Other projects I contribute to: scalaxb, an XML databinding tool for Scala (author) treehugger.scala (author) scopt/scopt (maintainer) Twitter: @eed3si9n Github: @eed3si9n

Updated on February 10, 2022

Comments

  • Eugene Yokota
    Eugene Yokota over 2 years

    I am writing a client-side Swing application (graphical font designer) on Java 5. Recently, I am running into java.lang.OutOfMemoryError: Java heap space error because I am not being conservative on memory usage. The user can open unlimited number of files, and the program keeps the opened objects in the memory. After a quick research I found Ergonomics in the 5.0 Java Virtual Machine and others saying on Windows machine the JVM defaults max heap size as 64MB.

    Given this situation, how should I deal with this constraint?

    I could increase the max heap size using command line option to java, but that would require figuring out available RAM and writing some launching program or script. Besides, increasing to some finite max does not ultimately get rid of the issue.

    I could rewrite some of my code to persist objects to file system frequently (using database is the same thing) to free up the memory. It could work, but it's probably a lot work too.

    If you could point me to details of above ideas or some alternatives like automatic virtual memory, extending heap size dynamically, that will be great.

  • Mike Clark
    Mike Clark over 13 years
    In general I think the JVM will prefer to Garbage Collect (GC) rather than throw an OutOfMemoryError. Explicitly calling System.gc() after OutOfMemoryError might possibly help on some VMs/configurations, but I would not expect it to work very well in the general case. However, dropping unnecessary object references would definitely help in almost all cases.
  • Admin
    Admin over 12 years
    @mwangi Calling System.gc() directly from the code is generally a bad idea. It's just a suggestion to JVM that GC should be performed, but there's absolutely no guarantee that it will be performed.
  • ernesto
    ernesto over 11 years
    Any idea why we need to keep them in 1:1 or 1:1.5 ratio?
  • AndroidRaji
    AndroidRaji over 11 years
    hi bighostkim and cuongHuyTo, where is "Arguments"..i can able to see upto Run Configuration. Please tel me. My need to download and store nearly 2000 contacts from gmail. It crash due to out of memory exception
  • Petr Gladkikh
    Petr Gladkikh about 11 years
    OpenJDK and OracleJDK have bundled profiler - jvisualvm. If you want more conveniences I'd suggest commercial Yourkit.
  • CuongHuyTo
    CuongHuyTo about 10 years
    @AndroiRaji: you right click your mouse onto the Java class that has a runnable main (that is "public static void main(String[] args)"), then choose Run As - Run Configuration. Then "Arguments" is the tab right after the Main (you see the tabs Main, Arguments, JRE, Classpath, Source, Environment, Common).
  • Dr.jacky
    Dr.jacky over 7 years
    How to set this parameter for ever? Cause I'm using 'gradlew assemble' command.
  • Arayan Singh
    Arayan Singh almost 6 years
    Run->Run Configurations->Click on arguments->inside VM arguments type -Xms1g -Xmx2g
  • matbrgz
    matbrgz over 5 years
    Java WebStart is being phased out. I am not yet aware of a suitable replacement.
  • Philip Rego
    Philip Rego over 5 years
    JVMJ9VM007E Command-line option unrecognised: -Xmx Could not create the Java virtual machine. Downvote
  • Ashish
    Ashish over 5 years
    This is so true. I am trying to fix one issue where I'm getting OOM on AWT thread but if I use different new thread, I am not getting OOM issue. All I can find online is increase heap size for AWT thread.
  • PeakGen
    PeakGen over 5 years
    @Ash: Yes, fix the core problem instead of looking for plasters.
  • Davos
    Davos over 4 years
    Garbage collection and the memory management approach in Java was supposed to solve all these malloc-dealloc complications of its predecessors :( Of course I completely agree with this answer it's just a shame the defaults don't make it easy to write code with lean data-structures that are cleaned up ASAP.
  • Sal-laS
    Sal-laS almost 4 years
    How would it be for intellih?
  • Zsolt Sky
    Zsolt Sky almost 3 years
    I do not agree. You need to set it to some value initially. If it turns out to be insufficient it does not necessarily mean that your application is bad. Maybe you were too optimistic. It is a valid solution to set it to a higher value in this case.
  • MrSalesi
    MrSalesi over 2 years
    Use close unused object and array, say resultsSet.close(); fileOutputStream.close(); fileOutputStream.flush(); , I use resultsSet.close() and was working magically.