Memory Leak
  • The standard definition of a memory leak is a scenario that occurs when objects are no longer being used by the application, but the Garbage Collector is unable to remove them from working memory – because they’re still being referenced.
  • As a result, the application consumes more and more resources – which eventually leads to a fatal OutOfMemoryError.
  • We will see a few scenarios.
Autoboxing
public class Adder {
public long addIncremental(long l)
{
Long sum=0L;
sum =sum+l;
return sum;
}
public static void main(String[] args) {
Adder adder = new Adder();
for(long i;i<1000;i++)
{
adder.addIncremental(i);
}
}
}
  • Instead of taking the primitive long for the sum, we took the Long (wrapper class), which is the cause of the memory leak.
  • Due to auto-boxing, sum=sum+l; creates a new object in every iteration, so 1000 unnecessary objects will be created.
Using Cache
public class Cache {
private Map<String,String> map= new HashMap<String,String>();
public void initCache()
{
map.put("Ashish", "Work as Engineer");
map.put("Rishab", "Work as Java Engineer");
map.put("Arun", "Work as Doctor");
}
public Map<String,String> getCache()
{
return map;
}
publicvoid forEachDisplay()
{
for(String key : map.keySet())
{
String val = map.get(key);
System.out.println(key + " :: "+ val);
}
}
public static void main(String[] args) {
Cache cache = new Cache();
cache.initCache();
cache.forEachDisplay();
}
}
  • Here, a memory leak occurs due to the internal map data structure. This class is to display the employee value from the cache.
  • Once those are displayed, there is no need to store those elements in the cache.
  • We forgot to clear the cache, so although objects in cache are not required anymore by the application, it can’t be GCed, as map holds a strong reference to them.
  • Alternatively, you can initialize the cache by WeakHashMap.
  • The beauty of WeakHashMap is, if keys are not referenced by any other objects, then that entry will be eligible for GC.
Closing Connections
try
{
Connection con = DriverManager.getConnection();
...
con.close();
}
catch(exception ex)
{
}
  • In the above example, we close the connection (Costly) resource in the try block, so in the case of an exception, the connection will not be closed.
  • So it creates a memory leak as this connection never returns back to the pool.
  • Please always put any closing stuff in the finally block.
Using CustomKey

public class CustomKey {
public CustomKey(String name)
{
this.name=name;
}

private String name;

public static void main(String[] args) {
Map<CustomKey,String> map = new HashMap<CustomKey,String>();
map.put(new CustomKey("Shamik"), "Shamik Mitra");
String val = map.get(new CustomKey("Shamik"));
System.out.println("Missing equals and hascode so value is not accessible from Map " + val);
}
}
  • As in CustomKey, we forgot to provide equals() and hashcode() implementation, so a key and value stored in the map can’t be retrieved later, as the map get() method checks hashcode() and equals().
  • But this entry is not able to be GCed, as the map has a reference to it, but application can’t access it. Definitely a memory leak.
  • So when you make your Custom key, always provide an equals and hashcode() implementation.

 

Categories: JAVA

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *