Wednesday, October 01, 2014

Java Memory leaks

Causes of memory leaks in Java
The four typical causes of memory leaks in a Java program are:
  1. Unknown or unwanted object references: These objects are no longer needed, but the garbage collector can not reclaim the memory because another object still refers to it.
  1. Long-living (static) objects: These objects stay in the memory for the application's full lifetime. Objects tagged to the session may also have the same lifetime as the session, which is created per user and remains until the user logs out of the application. Example: Listeners, Static Collection classes, Connections, JNI
  1. Failure to clean up or free native system resources: Native system resources are resources allocated by a function external to Java, typically native code written in C or C++. Java Native Interface (JNI) APIs are used to embed native libraries/code into Java code.
  1. Bugs in the JDK or third-party libraries: Bugs in various versions of the JDK or in the Abstract Window Toolkit and Swing packages can cause memory leaks.

Symptoms
  • Causes Out of memory after some time
  • GC keeps reclaiming lesser heap each time (memory used for long lived objects increase over time)
  • Causes frequent full GC
  • Available free heap decreases each time
  • Response time decreases

Detection of  Memory leaks
  • Add JVM args to collect GC metrics --> verbose:gc,-XX:+PrintGCTimeStamps,-XX:+PrintGCDetails
  • Monitor heap. If heap size increases after each full GC, this means a memory leak.
  • Use HeapDumpOnOutOfMemoryError to dump heal to a file
  • Use JMAP to dump heap and analyze using visualVM
    • jmap -dump:file=xyz.log PID
  • Use profilers

Other technique to detect memory leak
So Java Memory Leaks occur when objects still have a GC root reference, but are not actually used anymore. Those “Loitering Objects” stay around for the whole life of the JVM. If the application is creating those “dead objects” on and on, the memory will be filled up and eventually result in a java.lang.OutOfMemoryError. Typical causes are static collections, which are used as a kind of cache. Usually objects are added, but never removed (Let’s face it: How often have you used add() and put() and how often used remove() methods?). Because the objects are referenced by the static collection, they cannot be freed up anymore, as the collection has a GC root reference via the classloader.

Examples of memory leaks
Not closing resultset and statement objects explicitly…

No comments: