Sunday, February 14, 2010

How to prevent OOME? Memory Leak analysis...


What is Memory Leak and how it affects everything in your server? First, Memory Leak is not good. Memory leaks are hard to detect especially when using frameworks or third party library that you didn’t created. Seconds, it affects everything when you deploy it in production environment and don’t care about memory leak until your server is down. If you want to keep the server run 24 x 7, check for memory leak.

In Java, Garbage Collector (GC) is your friend, it collects and handles most of the memory leak issue by default but it still requires help from your code. The GC is just a temporary workaround. When creating an application that use memory as storage, make sure that you clean your own mess. Don’t depend on GC because GC sometimes it ignores your object to be collected because GC doesn’t have a way to identify if your application is really using the object. Memory leak usually cause when an object in JVM are not accessible by a running thread and also caused by a Rogue Thread.

Rogue Thread is an unmanageable thread. No application can control it and it is caused when there is an application running and in the middle, the application stop. Another cause of memory leak is a Circular Reference, on my previous job, I always tell my colleagues to make sure that they’re not doing a circular reference because it’s like doing an infinite loop.


Lesson learned about Memory Leak and what to do:
1.    Stress testing is necessary if you’re application is for multithreaded.
2.    Utilize the tools that Java JDK provided.
3.    Take care of your code before sending it to production.
4.    NEVER EVER BLAME THE SERVER. Server is just another folder in your windows OS.
5.    To be continued…
Basic tips for performance:
1.    Try to minimize the use of STATIC object.
2.    Convert “+” concatenation into StringBuffer or StringBuilder.
3.    Understand GC.

How I search for memory leak?

Simple, use the tools that you already have. The question is how to use it? Anyway, I listed the approach below. Note: You must use JDK 6 or higer

HotSpotDiagnosticMXBean
ManagementFactory.getDiagnosticMXBean().dumpHeap("\temp\heapdump_apps.bin", true);
After getting the heapdump, use the jVisualVM to find the leak.
-XX:HeapDumpOnCtrlBreak
The -XX:HeapDumpOnCtrlBreak option adds the hprofdump diagnostic command to the list of commands that run automatically when the Ctrl-break keys are pressed (similar to the print_threads diagnostic command). The HPROF dump file is written to the location defined by the -XX:HeapDumpPath option. Add this option when running JVM. It will create heap dump every time ctrl+break (kill -3) signal is sent to JVM.

-XX:+HeapDumpOnOutOfMemoryError
If you application throws an OutOfMemoryError, it will create a heap dump (.hprof file) into a binary format. You need to add –XX:HeapDumpPath option to define the location of your heap dump file.

jMap –dump:file=.bin
jMap is the tools that I’ve been using to generate heap dump. It comes with JDK install. is just file name and is your application process_id. In unix, you can get this by “ps eaf”, in windows use the “jps” to get the process ID.

Use jMap in the code
All you need to do is create a simple java class and add the code to your main method.

String appName= ManagementFactory.getRuntimeMXBean().getName()
String processId  = appName.substring(0, appName.indexOf("@"));
String [] myCmd = {"jmap", "-dump:file=/tmp/appHeapDump.bin", processId};
Process proc = Runtime.getRuntime().exec(cmd);