views:

40577

answers:

11

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.

+30  A: 

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 happens 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.

Ben Childs
+14  A: 

@jjnguy: -Xms sets the initial size of the heap. Changing this will have no effect on java.lang.OutOfMemory errors. The option to use is -Xmx which sets the maximum size of the heap. See here for details.

Dave Webb
+4  A: 

Yes, with -Xmx you can configure more memory for you 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.

kohlerm
A: 

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.

Leigh
+1  A: 

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 Kapersky 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, -Xmx1600 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.

David
+1  A: 

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 a operating system specific launcher which sets the arguments you need.

Thorbjørn Ravn Andersen
A: 

I am getting same erro java.lang.OutOfMemoryError: Java heap space at the time of running web application often in local envirnoment. I have also tried to increase heap space, but I found that it is not the permanent soultion.

I have gone thru whole source of this web application, and I have found that other programmers has used lots of final static objects as class variables, which are not re-useable most of the time, and these type of objects has not been de-referenced to null, hence these objects are not to force for garbage collection. (I am assuming this scenario)

Can anybody tell me that is it adviceable to make final static onjects in application?

As per my best knowledge final static object's scope will remain till server is running, that is why this type of error occurs.

Can anybody guide me on this topic?

Thanks in Advance

See the accepted answer. There is a type of program called profiler that can analyze the exact usage of the memory. I suggest you run it at least once to find out who's actually hogging the memory.
eed3si9n
Just seeing this now, but very likely run out of perm space. Graph your GC logs and increase permsize -XX:MaxPermSize=XXXm as necessary.
Xepoch
A: 

David Hausheer

Web hausheer.osola.com Home CV Guestbook Japan Gallery latex2png Links CFPs Publications Bibliography Docs Software Contact

If Java runs out of memory, the following error occurs:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space This can have two reasons:

Your Java application has a memory leak. There are tools like YourKit Java Profiler that help you to identify such leaks. Your Java application really needs a lot of memory (more than 128 MB by default!). In this case the Java heap size can be increased using the following runtime parameters: java -Xms -Xmx Defaults are:

java -Xms32m -Xmx128m You can set this either in the Java Control Panel or on the command line, depending on the environment you run your application.

Yoginder Pal
Joachim Sauer
A: 

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 alot 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();
mwangi
A: 

I am having a similar trouble with my UNIX server which has Openfire running in Java. How can increase the Heap Size from command line. Or do i need to make change in the source file of Open fire where the allocation has been defined. Any help would be appreciate it.

org.jivesoftware.openfire.nio.ConnectionHandler.exceptionCaught(ConnectionHandler.java:110) java.lang.OutOfMemoryError: Java heap space

Ashrocks
Please read the answers posted here, and if it doesn't solve it post it as a separate question. This is the section for answers not more questions.
eed3si9n
A: 

If you keep on allocating & keeping references to object, you will fill up any ammount 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...

SoulWanderer