views:

716

answers:

6

Hello,

I've been tasked with debugging a Java (J2SE) application which after some period of activity begins to throw OutOfMemory exceptions. I am new to Java, but have programming experience. I'm interested in getting your opinions on what a good approach to diagnosing a problem like this might be?

This far I've employed JConsole to get a picture of what's going on. I have a hunch that there are object which are not being released properly and therefor not being cleaned up during garbage collection.

Are there any tools I might use to get a picture of the object ecosystem? Where would you start?

+3  A: 

I'd start with a proper Java profiler. JConsole is free, but it's nowhere near as full featured as the ones that cost money. I used JProfiler, and it was well worth the money. See http://stackoverflow.com/questions/14762/please-recommend-a-java-profiler for more options and opinions.

Paul Tomblin
Thanks for the heads up. After about 30 minutes spent configuring the profiler integration I was able to find the source of the memory leak in about 5 minutes. Appreciate the suggestion.
Matty
+3  A: 

Try the Eclipse Memory Analyzer, or any other tool that can process a java heap dump, and then run your app with the flap that generates a heap dump when you run out of memory.

Then analyze the heap dump and look for suspiciously high object counts.

See this article for more information on the heap dump.

EDIT: Also, please note that your app may just legitimately require more memory than you initially thought. You might try increasing the java minimum and maximum memory allocation to something significantly larger first and see if your application runs indefinitely or simply gets slightly further.

Richard Campbell
I wish I could direct link to my comment about EMA in another thread, but I can't recommend this enough. EMA is able to open a heap dump log file of ~400mb in less than 5 minutes for me, while jhat took 70+ minutes to read it before it crashed the JVM (was never able to even open it all the way).
matt b
+1  A: 

http://www.yourkit.com/download/index.jsp is the only tool you'll need. You can take snapshots at (1) app start time, and (2) after running app for N amount of time, then comparing the snapshots to see where memory gets allocated. It will also take a snapshot on OutOfMemoryError so you can compare this snapshot with (1).

For instance, the latest project I had to troubleshoot threw OutOfMemoryError exceptions, and after firing up YourKit I realised that most memory were in fact being allocated to some ehcache "LFU " class, the point being that we specified loads of a certain POJO to be cached in memory, but us not specifying enough -Xms and -Xmx (starting- and max- JVM memory allocation).

I've also used Linux's vmstat e.g. some Linux platforms just don't have enough swap enabled, or don't allocate contiguous blocks of memory, and then there's jstat (bundled with JDK).

UPDATE see http://stackoverflow.com/questions/14762/please-recommend-a-java-profiler

opyate
A: 

You can also add an "UnhandledExceptionHandler" to your Application's Thread. This will catch 'uncaught' exception, like an out of memory error, and you will at least have an idea where the exception was thrown. Usually this not were the problem is but the 'new' that couldn't be satisfied. As a rule I always add the UnhandledExceptionHandler to a Thread if nothing else to add logging.

Javamann
A: 

+1 on JProfiler.

Javamann
Would be better to just +1 the existing JProfiler answer, than create a new one, no?
Software Monkey
+2  A: 

The latest version of the Sun JDK includes VisualVM which is essentially the Netbeans profiler by itself. It works really well.

Jay R.