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.
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()
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.
This particular memory leak was caused by a misconfigured Hibernate
I wrote about earlier.