PDA

View Full Version : What a memory leak looks like


kjkoster
13-12-2008, 21:14
Dear All,

Here is what a memory leak looks like. This is a bad one, actually, chugging through 512MB RAM in a day or so. These are easy to spot, as your server goes down hard after 24 hours.

http://java-monitor.com/misc/memoryleak.png

The thing to look for (according to Kirk Pepperdine) is to look at the bottom of the graph. If that line walks up slowly, you may have a memory leak. If the top flaps wildly, but the bottom of the graph is stable, you are probably safe.

If you look at the graph you see the maximum memory setting (about 512MB) at the top of the graph. The red line does not show properly, but you can take the top border of the image as being 512MB.

The blue line is the amount of memory that has been requested from the operating system by the virtual machine. In systems that only temporarily require more memory, you can see the blue line go down too, as the JVM returns memory to the OS for other tasks to use. This way, the JVM keeps the heap reasonably small, even for systems that have ridiculously high -Xmx values.

My opinion is not to set -Xmx and -Xms to the same values. This keeps the JVM in charge of managing memory, rather than me. In my experience, the JVM does a better job. :)

Note that this is where Runtime.freeMemory() ("http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#freeMemory()) shows its true uselessness. That value is calculated against the committed memory (the blue line) and not the max memory (the red line/top border of the image). So reading that value does not actually tell you anything useful at all.

Another nugget is in the accompanying GC graph. Look at the graph below. Notice how the JVM just gives up on the PS Scavenge collector and starts using the PS MarkSweep collector. The latter is a lot more expensive in terms of run-time overhead, but it finds more garbage to collect, usually. The JVM does everything in its power to not have to resort to using it. In this case, because memory is so low that the JVM sees no alternative. In fact, it just stops using the PS Scavenge collector altogether and only uses the hugely expensive PS MarkSweep collector.

Note how switching from PS Scavenge to PS MarkSweep signals an impending out of memory situation. This is one to watch for.

http://java-monitor.com/misc/memoryleak-gc.png

This particular memory leak was caused by a misconfigured Hibernate (http://java-monitor.com/forum/showthread.php?t=149) I wrote about earlier.

Kees Jan

kjkoster
21-12-2008, 11:09
Dear All,

Christopher Schultz on the Tomcat Users list pointed out that it is not clear from the graph that what causes the graph to go back down is a system restart (http://www.mail-archive.com/users@tomcat.apache.org/msg54387.html). He thought that the graph went back down because of a major GC.

That is of course a vital bit of information I left out. Sorry for the confusion. So, to recap: these memory leaks are easy to spot and obvious, if you have to reboot the system and you get a graph like this. :-)

Chris also argues that for Java production servers, it makes sense to set -Xmx and -Xms to the same value always. This reduces the overhead of allocating memory from the operating system. I have to revise my earlier statement. I agree that he's right and that you should have -Xmx and -Xms set to the same values for production machines.

If you have a production machine that is starved for memory, you need to visit your local hardware store more often. Memory is not exactly expensive these days. :)

Kees Jan