Detecting and fixing memory leak in java




Contents of page >
  • 1) What is memory leak in java?
  • 2) Consequences of memory leak in java>
  • 3) Scenarios where memory leak can happen in java >
    • 3.1) Static variables/ fields are not garbage collected and can cause memory leak in java >
    • 3.2) Thread Local Variables can cause memory leak in java >
    • 3.3) Memory leak while using Autoboxing and unboxing in java >
    • 3.4) Avoid memory leak using WeakHashMap in java >
    • 3.5) Using custom key in map without Overriding equals() and hashCode() method can cause memory leak >
    • 3.6) Close DBC Statement, PreparedStatement, CallableStatement , ResultSet and Connections in java to avoid memory leaks >
    • 3.7) Memory leaks can also be caused by native methods in java >
    • 3.8) Memory leak in web applications in java >
  • 4) You can detect memory leaks using following 10 ways -



At times detecting a slow memory leak can become very difficult.


1) What is memory leak in java?
Memory leak happens when number of objects(these objects are not needed) created becomes large and time spent in garbage collection increases.

Ultimately application becomes very slow, non responsive and ends up throwing  OutOfmemoryError.

“Memory leaks ends up throwing OutOfmemoryError but OutOfmemoryError doesn’t means memory leak in java”.


2) Consequences of memory leak in java>
  • Application becomes very slow.
  • Time spent in garbage collection increases.
  • And ultimately OutOfmemoryError is thrown in java.


3) Scenarios where memory leak can happen in java >

3.1) Static variables/ fields are not garbage collected and can cause memory leak in java >

Can Static variables be garbage collected in some scenario?
Static variables are only garbage collected when the class loader which has loaded the class in which static field is there is garbage collected.

So, be cautious as these static variables can create a memory leak in java.

For more details click here - Static variables are not garbage collected?




3.2) Thread Local Variables can cause memory leak in java >

A thread local variable is member field in the Thread class.
Such thread local variable can be used to hold the thread state.
But, thread local variable aren’t garbage collector till thread is alive.
So, be cautious as these thread local variable can create a memory leak in java.

Also read about ThreadLocal in multithreading in java





3.3) Memory leak while using Autoboxing and unboxing in java >

For addition of numbers we must prefer to use primitive data type, not the Object wrapper class.
Addition of numbers using Integers turns out into very costly operation in terms of performance, boxing/unboxing and unnecessary object formations.
Just imagine a situation where 1000000’s... of number are being added using Integer, it will literally explode our heap memory and boxing/unboxing operations will have adverse effect on performance.



If Integer has to added to Integer than first both will be converted to int in java >
public class AutoboxingCanCauseMemoryLeak1 {
   public static void main(String[] args) {
          Integer i1 = 4;
          Integer i2 = 5;
          Integer i3 = 0;
         
          for (int i = 0; i < 100; i++) {
                 i3 = i1 + i2 + i3 ;
          }
          System.out.println(i3);
   }
}
/* output
900
*/

In above program we are adding Integer to Integer.
  • First Integers will be unboxed to int,
  • then ints are added and result is int
  • Ultimate result (i.e. int) is autoboxed to Integer.

Java compiler will convert above code into -
public class AutoboxingCanCauseMemoryLeak2 {
   public static void main(String[] args) {
          Integer i1 = Integer.valueOf(4);
          Integer i2 = Integer.valueOf(5);
          Integer i3 = new Integer(0) ;
         
          for (int i = 0; i < 100; i++) {
                 i3 = Integer.valueOf(i1.intValue() + i2.intValue() + i3.intValue());
          }
          System.out.println(i3);
   }
}
/* output
900
*/

So, Addition of numbers using Integers turns out into very costly operation in terms of performance, boxing/unboxing and unnecessary object formations, because it creates memory leak.

Solution of above memory leak >
For addition of numbers we must prefer to use primitive data type, not the Object wrapper class.

public class AutoboxingMemoryLeakSolved {
   public static void main(String[] args) {
          int i1 = 4;
          int i2 = 5;
          int i3 = 0;
         
          for (int i = 0; i < 100; i++) {
                 i3 = i1 + i2 + i3 ;
          }
          System.out.println(i3);
   }
}
/* output
900
*/




3.4) Avoid memory leak using WeakHashMap in java >
WeakHashMap is hash table based implementation of the Map interface, with weak keys.
An entry in a WeakHashMap will be automatically removed by garbage collector when its key is no longer in ordinary use. Mapping for a given key will not prevent the key from being discarded by the garbage collector, (i.e. made finalizable, finalized, and then reclaimed). When a key has been discarded its entry is removed from the map in java.

So, using WeakHashMap in place of HashMap can help us in avoiding memory leaks.

For more details read : WeakHashMap in java




3.5) Using custom key in map without Overriding equals() and hashCode() method can cause memory leak >
How using custom key in map without Overriding equals() and hashCode() method can cause memory leak? Let's learn about that in detail.
If custom key is used and equals() and hashCode() method are not overridden then, key will not be retrieved by using get() method.
Because get() method internally calls equals() and hashCode() method for retrieving keys.
So, these keys will neither be used nor be garbage collected, so it’s a clear case of memory leak.
This also causes memory leak when keys are added using put() method.

So,  to avoid memory leak while using custom key you must always  
Learn how you can use custom key (Employee object) in custom HashMap Custom implementation - put, get, remove


For more details read : How Integer is used as key in Hashmap


3.6) Close DBC Statement, PreparedStatement, CallableStatement , ResultSet and Connections in java to avoid memory leaks >
You must ensure that you close all the JDBC Statement, PreparedStatement, CallableStatement , ResultSet and Connections in java to avoid memory leaks. You must always close all the above mentioned objects in finally block in java because finally block is always executed irrespective of exception is thrown or not by java code.
Example of closing PreparedStatement, ResultSet and Connections in finally block in java-

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class JdbcBestPracticeExampleInJava {
   public static void main(String... arg) {
          Connection con = null;
          PreparedStatement prepStmt = null;
          ResultSet rs = null;                 
          try {
                 // Logic ..
          } catch (ClassNotFoundException e) {
                 e.printStackTrace();
          } catch (SQLException e) {
                 e.printStackTrace();
          }
          finally{
                 try {
                       if(rs!=null) rs.close(); //close resultSet
                       if(prepStmt!=null) prepStmt.close(); //close PreparedStatement
                       if(con!=null) con.close(); // close connection
                 } catch (SQLException e) {
                       e.printStackTrace();
                 }
          }
   }
}

For more read : Java JDBC best practices tutorial



3.7) Memory leaks can also be caused by native methods in java >
Memory allocated through native methods can cause some serious memory leak.

3.8) Memory leak in web applications in java >
Unused Objects stored in application scope are memory leak because they are not collected until web application is stopped.

4) You can detect memory leaks using following 10 ways - How to monitor and analyze the garbage collection in java
  1. JSTACK - Java stack traces
  2. Jstat  - Java Virtual Machine Statistics Monitoring Tool
  3. JHAT - Java Heap Analysis Tool.
  4. jconsole
  5. hprof
  6. eclipse plugin
  7. JFR (Java Flight Recorder)



Summary -

So in this core java tutorial we learned how to detect and fix memory leak in java.


Having any doubt? or you liked the tutorial! Please comment in below section.
Please express your love by liking JavaMadeSoEasy.com (JMSE) on facebook, following on google+ or Twitter.



RELATED LINKS>

Most important and frequently used VM (JVM) PARAMETERS with examples in JVM Heap memory in java



 

eEdit
Must read for you :