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

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.

This question is related to java jvm out-of-memory heap-memory

The answer is


If you need to monitor your memory usage at runtime, the java.lang.management package offers MBeans that can be used to monitor the memory pools in your VM (eg, eden space, tenured generation etc), and also garbage collection behaviour.

The free heap space reported by these MBeans will vary greatly depending on GC behaviour, particularly if your application generates a lot of objects which are later GC-ed. One possible approach is to monitor the free heap space after each full-GC, which you may be able to use to make a decision on freeing up memory by persisting objects.

Ultimately, your best bet is to limit your memory retention as far as possible whilst performance remains acceptable. As a previous comment noted, memory is always limited, but your app should have a strategy for dealing with memory exhaustion.


Note that if you need this in a deployment situation, consider using Java WebStart (with an "ondisk" version, not the network one - possible in Java 6u10 and later) as it allows you to specify the various arguments to the JVM in a cross platform way.

Otherwise you will need an operating system specific launcher which sets the arguments you need.


Yes, with -Xmx you can configure more memory for your JVM. To be sure that you don't leak or waste memory. Take a heap dump and use the Eclipse Memory Analyzer to analyze your memory consumption.


if you got this error when you launch eclipse birt 1- you will go in the file of the eclipse configuration 2- you must open eclipse.init 3- modified the RAM memory, you can increase this, i give an example.

my old information was : -Xmx128m -XX:MaxPermSize=128m

the new modification that i opered :

-Xmx512m -XX:MaxPermSize=512m

this modification will permit me to resolve java heap space when i launch my report in my browser.

Thanks


I would like to add recommendations from oracle trouble shooting article.

Exception in thread thread_name: java.lang.OutOfMemoryError: Java heap space

The detail message Java heap space indicates object could not be allocated in the Java heap. This error does not necessarily imply a memory leak

Possible causes:

  1. Simple configuration issue, where the specified heap size is insufficient for the application.

  2. Application is unintentionally holding references to objects, and this prevents the objects from being garbage collected.

  3. Excessive use of finalizers.

One other potential source of this error arises with applications that make excessive use of finalizers. If a class has a finalize method, then objects of that type do not have their space reclaimed at garbage collection time

After garbage collection, the objects are queued for finalization, which occurs at a later time. finalizers are executed by a daemon thread that services the finalization queue. If the finalizer thread cannot keep up with the finalization queue, then the Java heap could fill up and this type of OutOfMemoryError exception would be thrown.

One scenario that can cause this situation is when an application creates high-priority threads that cause the finalization queue to increase at a rate that is faster than the rate at which the finalizer thread is servicing that queue.


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.


Regarding to netbeans, you could set max heap size to solve the problem.

Go to 'Run', then --> 'Set Project Configuration' --> 'Customise' --> 'run' of its popped up window --> 'VM Option' --> fill in '-Xms2048m -Xmx2048m'.


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

In android studio add/change this line at the end of gradle.properties (Global Properties):

...
org.gradle.jvmargs=-XX\:MaxHeapSize\=1024m -Xmx1024m 

if it doesn't work you can retry with bigger than 1024 heap size.


I have faced same problem from java heap size.

I have two solutions if you are using java 5(1.5).

  1. just install jdk1.6 and go to the preferences of eclipse and set the jre path of jav1 1.6 as you have installed.

  2. Check your VM argument and let it be whatever it is. just add one line below of all the arguments present in VM arguments as -Xms512m -Xmx512m -XX:MaxPermSize=...m(192m).

I think it will work...


I read somewhere else that you can try - catch java.lang.OutOfMemoryError and on the catch block, you can free all resources that you know might use a lot of memory, close connections and so forth, then do a System.gc() then re-try whatever you were going to do.

Another way is this although, i don't know whether this would work, but I am currently testing whether it will work on my application.

The Idea is to do Garbage collection by calling System.gc() which is known to increase free memory. You can keep checking this after a memory gobbling code executes.

//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);

Runtime runtime = Runtime.getRuntime();

if(runtime.freeMemory()<minRunningMemory)
 System.gc();

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. This is my preferred solution when I get OutOfMemoryError in Eclipse, Maven or ANT while building project because based upon size of project you can easily ran out of Memory.

Here is an example of increasing maximum heap size of JVM, Also its better to keep -Xmx to -Xms ration either 1:1 or 1:1.5 if you are setting heap size in your java application.

export JVM_ARGS="-Xms1024m -Xmx1024m"

Reference Link


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

If this issue is happening in Wildfly 8 and JDK1.8,then we need to specify MaxMetaSpace settings instead of PermGen settings.

For example we need to add below configuration in setenv.sh file of wildfly. JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"

For more information, please check Wildfly Heap Issue


By default for development JVM uses small size and small config for other performance related features. But for production you can tune e.g. (In addition it Application Server specific config can exist) -> (If there still isn't enough memory to satisfy the request and the heap has already reached the maximum size, an OutOfMemoryError will occur)

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size

-XX:ParallelGCThreads=8
-XX:+CMSClassUnloadingEnabled
-XX:InitiatingHeapOccupancyPercent=70
-XX:+UnlockDiagnosticVMOptions
-XX:+UseConcMarkSweepGC
-Xms512m
-Xmx8192m
-XX:MaxPermSize=256m (in java 8 optional)

For example: On linux Platform for production mode preferable settings.

After downloading and configuring server with this way http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/

1.create setenv.sh file on folder /opt/tomcat/bin/

   touch /opt/tomcat/bin/setenv.sh

2.Open and write this params for setting preferable mode.

nano  /opt/tomcat/bin/setenv.sh 

export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=8"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+CMSClassUnloadingEnabled"
export CATALINA_OPTS="$CATALINA_OPTS -XX:InitiatingHeapOccupancyPercent=70"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UnlockDiagnosticVMOptions"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseConcMarkSweepGC"
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256M"

3.service tomcat restart

Note that the JVM uses more memory than just the heap. For example Java methods, thread stacks and native handles are allocated in memory separate from the heap, as well as JVM internal data structures.


If everything else fails, in addition to increasing the max heap size try also increasing the swap size. For Linux, as of now, relevant instructions can be found in https://linuxize.com/post/create-a-linux-swap-file/.

This can help if you're e.g. compiling something big in an embedded platform.


Follow below steps:

  1. Open catalina.sh from tomcat/bin.

  2. Change JAVA_OPTS to

    JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m 
    -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m 
    -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
    
  3. Restart your tomcat


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

See here for details.


VM arguments worked for me in eclipse. If you are using eclipse version 3.4, do the following

go to Run --> Run Configurations --> then select the project under maven build --> then select the tab "JRE" --> then enter -Xmx1024m.

Alternatively you could do Run --> Run Configurations --> select the "JRE" tab --> then enter -Xmx1024m

This should increase the memory heap for all the builds/projects. The above memory size is 1 GB. You can optimize the way you want.


If you keep on allocating & keeping references to object, you will fill up any amount of memory you have.

One option is to do a transparent file close & open when they switch tabs (you only keep a pointer to the file, and when the user switches tab, you close & clean all the objects... it'll make the file change slower... but...), and maybe keep only 3 or 4 files on memory.

Other thing you should do is, when the user opens a file, load it, and intercept any OutOfMemoryError, then (as it is not possible to open the file) close that file, clean its objects and warn the user that he should close unused files.

Your idea of dynamically extending virtual memory doesn't solve the issue, for the machine is limited on resources, so you should be carefull & handle memory issues (or at least, be carefull with them).

A couple of hints i've seen with memory leaks is:

--> Keep on mind that if you put something into a collection and afterwards forget about it, you still have a strong reference to it, so nullify the collection, clean it or do something with it... if not you will find a memory leak difficult to find.

--> Maybe, using collections with weak references (weakhashmap...) can help with memory issues, but you must be carefull with it, for you might find that the object you look for has been collected.

--> Another idea i've found is to develope a persistent collection that stored on database objects least used and transparently loaded. This would probably be the best approach...


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to jvm

Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 How can I get a random number in Kotlin? Kotlin unresolved reference in IntelliJ Is JVM ARGS '-Xms1024m -Xmx2048m' still useful in Java 8? Android Gradle Could not reserve enough space for object heap Android java.exe finished with non-zero exit value 1 Android Studio Gradle project "Unable to start the daemon process /initialization of VM" Android Studio - No JVM Installation found Android Studio error: "Environment variable does not point to a valid JVM installation" Installing Android Studio, does not point to a valid JVM installation error

Examples related to out-of-memory

Node.js heap out of memory How to solve java.lang.OutOfMemoryError trouble in Android Spark java.lang.OutOfMemoryError: Java heap space Android Studio - How to increase Allocated Heap Size Exception of type 'System.OutOfMemoryException' was thrown. How do you add swap to an EC2 instance? "java.lang.OutOfMemoryError : unable to create new native Thread" .NET Out Of Memory Exception - Used 1.3GB but have 16GB installed Maven Out of Memory Build Failure Unable to execute dex: GC overhead limit exceeded in Eclipse

Examples related to heap-memory

Node.js heap out of memory Set default heap size in Windows how to increase java heap memory permanently? What is the largest possible heap size with a 64-bit JVM? Tomcat 7: How to set initial heap size correctly? Heap space out of memory C: How to free nodes in the linked list? java.lang.OutOfMemoryError: GC overhead limit exceeded How is the default max Java heap size determined? How to increase Java heap space for a tomcat app