How do you avoid the memory leakage problem in your java project?
How do you get to know if there is a memory leakage problem in your project?
Symptoms of a Memory leak
- Works fine with small data sets, severe performance issues with large data sets
- Ever increasing Old-Generation memory usage in your JVM
- Out-of-Memory Heap errors in your JVM
- Spontaneous crashes.
A memory leak in Java can occur if you forget to close a resource, or references to objects are unnecessarily maintained.
When no more memory is remaining, an OutOfMemoryError alert will be thrown and generate an exception like this:
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space at XXX
Not every OutOfMemoryError alert indicates that a program is suffering from a memory leak. Some programs simply need more memory to run. In other words, some OutOfMemoryError alerts are caused by the load, and as a result they indicate the need for more memory in a program rather than a memory leak.
To distinguish between a memory leak and an application that simply needs more memory, we need to look at the “peak load” concept. When program has just started no users have yet used it, and as a result it typically needs much less memory then when thousands of users are interacting with it. Thus, measuring memory usage immediately after a program starts is not the best way to gauge how much memory it needs! To measure how much memory an application needs, memory size measurements should be taken at the time of peak load—when it is most heavily used.
The primary characteristic of memory leaks is that memory requirements increase as a function of time, not as a function of the load.
If memory usage is growing over a period of a few days, and the program eventually started suffering from OutOfMemory exceptions, it would be a very strong indication that there’s a problem with memory leaks.
You need to measure memory that is free and used inside of the JVM, not memory that the JVM process is using. In other words, the top/Task Manager/Activity Monitor will measure how much memory your Java process is using, but that’s not what you need. You need a tool that can look inside the JVM process and tell you how much memory is available for your program running inside the JVM.
What you need to investigate is not current memory usage, but rather the average usage over a long period of time.The simplest method to measure the amount of memory a program uses, which does not require any tools and works even with production systems, is the Verbose GC log.
Verbose GC Log
The Verbose GC log is defined when the JVM process is started. There are a couple of switches that can be used:
- -verbose:gc — prints basic information about GC to the standard output
- -XX:+PrintGCTimeStamps — prints the times that GC executes
- -XX:+PrintGCDetails — prints statistics about different regions of memory in the JVM
- -Xloggc:<file> — logs the results of GC in the given file
You can also take Java heap dump and take a look at the memory and find out what’s really causing the memory leak. JDK has a tool called jhat, which you can use to inspect the heap dump.
Analyzing the heap dump is done in order to:
- Find objects that are “leaking”
- Find the root cause of the memory leak
To determine which objects are leaked, sort the classes by total memory usage of all instances of each class. The objects near the top of the list are usually the leaked objects. Then, you can follow the reference chain to them until you find the cause of the memory leak.