Friday, November 2, 2007

Common causes for memory leaks in Java applications

1) Unbounded caches
A very simple example of a memory leak would be a java.util.Collection object (for example, a HashMap) that is acting as a cache but which is growing without any bounds.

public class MyClass {
static HashSet myContainer = new HashSet();
public void leak(int numObjects) {
for (int i = 0; i < numObjects; ++i) {
String leakingUnit = new String("this is leaking object: " + i);
myContainer.add(leakingUnit);
}
}
public static void main(String[] args) throws Exception {
{
MyClass myObj = new MyClass();
myObj.leak(100000); // One hundred thousand
}
System.gc();
}


In the above program, there is a class with the name MyClass which has a static reference to HashSet by the name of myContainer. In the main method of the class: MyClass, (in bold text) within which an instance of the class: MyClass is instantiated and its member operation: leak is invoked. This results in the addition of a hundred thousand String objects into the container: myContainer. After the program control exits the subscope, the instance of the MyClass object is garbage collected, because there are no references to that instance of the MyClass object outside that subscope. However, the MyClass class object has a static reference to the member variable called myContainer. Due to this static reference, the myContainer HashSet continues to persist in the Java heap even after the sole instance of the MyClass object has been garbage collected and, along with the HashSet, all the String objects inside the HashSet continue to persist, holding up a significant portion of the Java heap until the program exits the main method.

This program demonstrates a basic memory leaking operation involving an unbounded growth in a cache object. Most caches are implemented using the Singleton pattern involving a static reference to a top level Cache class as shown in this example.


Here is the GC information for you for the above snippet....

[GC 512K->253K(1984K), 0.0018368 secs]
[GC 765K->467K(1984K), 0.0015165 secs]
[GC 979K->682K(1984K), 0.0016116 secs]
[GC 1194K->900K(1984K), 0.0015495 secs]
[GC 1412K->1112K(1984K), 0.0015553 secs]
[GC 1624K->1324K(1984K), 0.0014902 secs]
[GC 1836K->1537K(2112K), 0.0016068 secs]
[Full GC 1537K->1537K(2112K), 0.0120419 secs]
[GC 2047K->1824K(3136K), 0.0019275 secs]
[GC 2336K->2035K(3136K), 0.0016584 secs]
[GC 2547K->2248K(3136K), 0.0015602 secs]
[GC 2760K->2461K(3136K), 0.0015517 secs]
[GC 2973K->2673K(3264K), 0.0015695 secs]
[Full GC 2673K->2673K(3264K), 0.0144533 secs]
[GC 3185K->2886K(5036K), 0.0013183 secs]
[GC 3398K->3098K(5036K), 0.0015822 secs]
[GC 3610K->3461K(5036K), 0.0028318 secs]
[GC 3973K->3673K(5036K), 0.0019273 secs]
[GC 4185K->3885K(5036K), 0.0019377 secs]
[GC 4397K->4097K(5036K), 0.0012906 secs]
[GC 4609K->4309K(5036K), 0.0017647 secs]
[GC 4821K->4521K(5036K), 0.0017731 secs]
[Full GC 4521K->4521K(5036K), 0.0222485 secs]
[GC 4971K->4708K(8012K), 0.0042461 secs]
[GC 5220K->4920K(8012K), 0.0018258 secs]
[GC 5432K->5133K(8012K), 0.0018648 secs]
[GC 5645K->5345K(8012K), 0.0018069 secs]
[GC 5857K->5558K(8012K), 0.0017825 secs]
[GC 6070K->5771K(8012K), 0.0018911 secs]
[GC 6283K->5984K(8012K), 0.0016350 secs]
[GC 6496K->6197K(8012K), 0.0020342 secs]
[GC 6475K->6312K(8012K), 0.0013560 secs]
[Full GC 6312K->6118K(8012K), 0.0341375 secs]
[GC 6886K->6737K(11032K), 0.0045417 secs]
[GC 7505K->7055K(11032K), 0.0027473 secs]
[GC 7823K->7374K(11032K), 0.0028045 secs]
[GC 8142K->7693K(11032K), 0.0029234 secs]
[GC 8461K->8012K(11032K), 0.0027353 secs]
[GC 8780K->8331K(11032K), 0.0027790 secs]
[GC 9099K->8651K(11032K), 0.0028329 secs]
[GC 9419K->8970K(11032K), 0.0027895 secs]
[GC 9738K->9289K(11032K), 0.0028037 secs]
[GC 10057K->9608K(11032K), 0.0028161 secs]
[GC 10376K->9927K(11032K), 0.0028482 secs]
[GC 10695K->10246K(11032K), 0.0028858 secs]
[GC 11014K->10565K(11416K), 0.0029284 secs]
[Full GC 10565K->10565K(11416K), 0.0506198 secs]
[GC 11781K->11071K(18956K), 0.0035594 secs]
[GC 12287K->11577K(18956K), 0.0042315 secs]
[GC 12793K->12082K(18956K), 0.0043194 secs]
[GC 12843K->12390K(18956K), 0.0030633 secs]
[GC 13606K->13494K(18956K), 0.0085937 secs]
[Full GC 13782K->13613K(18956K), 0.0646513 secs]




2) Infinite Loops

Some memory leaks occur due to program errors in which infinite loop in the application code allocates new objects and adds them to a data structure accessible from outside the program loop scope. This type of infinite loops can sometimes occur due to multithreaded access into a shared unsynchronized data structure. These types of memory leaks manifest as fast growing memory leaks, where if the verbose GC data reports a sharp drop in free heap space in a very short time leads to an OutOfMemoryError.
Friends please add more to this post... dying to see more in this post....

No comments:

Post a Comment