Expanding Heap

I wrote a little bowling game in Java a while back.

It was one of my first games and was a bit of a learning experience.

Anyway, I got my hands on a Java Profiler the other day and I ran this little game through it.

I noticed that the memory heap keeps getting a little bigger as the game progresses. It started out using around 4MB then climbed to 6MB and eventually started to slow down at around 9MB after 30 mintues or so.

However, the heap still seems to be growing slowly as the game continues to run. Garbage Collection seems to be releasing some memory, but not as much as I expected.

Is there anything in particular that I should look for in my code that would explain why more memory is not being released?

Thanks,

Drew

Collections that still hold objects that you aren’t going to use anymore. Maps are easy to fill with stuff you won’t access again.

Try a profiler:
http://www.manageability.org/blog/stuff/open-source-profilers-for-java

Hi Drew,

If your application is running on a PC, you can try the profiler in the Sun JVM. Try

java -Xrunhprofs:help

for help.
There is an option to display all objects still in memory when the application ends (

java -Xrunhprof:heap YourClass

and look at the content of the java.hprof.txt file for results). Well, graphical memory analyzers (like the Eclipse profile plugin) give you more than that, but this one is available almost everywhere…

There is also a command line flag in the sun VM to set the maximum heap. (-Xmx= I think but I forget. Use java -h and java -X to get a list of most of the commandline flags.)

Try setting your max heap and see if you eventually throw an out of memory error. if so, you are not freeing objects.

I didn’t have much luck dumping the heap with -Xrunhprof - kept getting an error.

However, I did use -Xmx4m as a test and let the program run for at least 30 minutes and it worked fine.

Yet, I’m still not sure why the heap keeps growing when no maximum is set even though I can get away with only 4MB.

Is this just how the VM normally behaves?

Also, how does one determine what the optimum min and max heap size is for a program?

Drew

I think it is absolutely possible and legal that the heap will grow to its limit (common 64MB). I also feel its not legal to make assumptions on how the GC works, when it will run and what it will do. Maybe it free some objects and lets others untouched until it is forced to care for them due to memory restrictions.

If you don’t get an OutOfMemoryException with a tight heap limit, your code is fine.

So it is ok to make the assumption that should allocation be attempted and no memory is left then the garbage collector will attempt to run and free some memory before the OutOfMemoryException is thrown?

Kev

Yes, absolutely. The GC must try a full collection before throwing OutOfMemory.

Cool, I’d always assumed so, but never seen it written down anywhere :wink:

Kev

Actually I think I worded that too strongly… “must” may not be correct, “will” is correct for current Sun VMs. As far as I know it might be “allowable” to never collect garbage at all.

So lesee… in order

(1) Yes, absolutely. The VM is trying to maximize the speed at which your program runs. If it can avoid GCs by growing memory then it will do so within the limits that you’ve set as acceptable with the command-line flags.

(2) Yes. The VM is required to make “all good faith efforts”, as they say in legal terms, to collect memory before it dies with an “out of memory” error. As pointed out this doesn’t mean that it will collect all, or anything, but it means it will TRY to collect all it can. (That caveat is because it is actually possible and legal to write a VM which never collects. IBM did this on some huge hardware with massive address spaces and massive disks where they just swapped data out and threw away address space until the end of the VM run and then cleaned up the disc and address space afterward.)

(3) Finding the right heap space for you app is an art. It starts by a static analysis of what you think your app is likely to use and continues with testing and measuring performance with various sized heaps. One thing to ALWAYS avoid on Win32 though is a heap so large it causes your app to swap as swapping performance is terrible on Wintel boxes.