Recent Posts

Thursday, 25 August 2016

Garbage Collection Tutorial


      In ‘C++’ the programmer is responsible for both creation and destruction of objects but usually the programmer is giving very much importance for creation of objects and he is ignoring the destruction of objects. Due to this at creation point of time there may not be sufficient memory for the creation of new objects and entire program may fails. But in java programmer is responsible only for creation of objects but sun people has introduced one assistance which is running continuously in the background for destruction of objects. Due to this assistance there is no chance of failing the java program due to memory problem, this assistance is nothing but “Garbage Collector”.

Ways to make an object eligible for Garbage Collector
  Even though the programmer is not responsible for destruction of objects it’s good programming practice to make an object eligible for Garbage Collector if it is no longer required.
     The following are different ways for this
1. Nullifying the reference Variable
     If an object is no longer required assign null to all its reference variables.
E.g
Student s1 = new Student();
Student s2 = new Student();
     Now No Object eligible for Garbage Collector
s1 = null
     Now One Object eligible for Garbage Collector
s2 = null
     Now Both Objects eligible for Garbage Collector

2. Reassigning the reference Variable
E.g
Student s1 = new Student();
Student s2 = new Student();
     Now No Object eligible for Garbage Collector
s1 = s2
     Now One Object eligible for Garbage Collector

The Objects Created inside a method
     The objects which are created in a method are by default eligible for Garbage Collector once the method completes.

E.g 1
class Test {
   public static void main(String arg[]){
      m1();
      // Both Objects eligible for Garbage Collector
   }
   public static void m1() {
      Employee e1 = new Employee();
      Employee e2 = new Employee();
   }
}
E.g 2
class Test {
   public static void main(String arg[]) {
      Employee s = m1();
      // One Object eligible for Garbage Collector 
   }
   public static Employee m1() {
      Employee e1 = new Employee();
      Employee e2 = new Employee();
      return e1;
   }
}
E.g 3
class Test {
   public static void main(String arg[]){
      m1();
      // Both Objects eligible for Garbage Collector
   }
   public static void m1() {
      Employee e1 = new Employee();
      Employee e2 = new Employee();
      return e1;
   }
}
The Island of Isolation
E.g
class Test {
   Test i;
   public static void main(String[] args) {
      Test t1 = new Test();
      Test t2 = new Test();
      Test t3 = new Test();
      t1.i = t2;
      t2.i = t3;
      t3.i = t1;
      // No Object eligible for Garbage Collector
      t1 = null;
      // No Object eligible for Garbage Collector
      t2 = null;
      // No Object eligible for Garbage Collector
      t3 = null;
      // All Objects eligible for Garbage Collector
   }
}
Note
1. If an object doesn’t have any reference variable that object is always eligible for Garbage Collection
2. Even though object having the reference variable still there may be a chance of that object eligible for Garbage Collection (Island of Isolation …Here ‘i’ is internal reference).

The methods to request JVM to run Garbage Collector
     We can request JVM to run Garbage Collector but there is no guarantee whether JVM accepts our request or not. We can do this by using the following ways.
By System class
     System class contains a static ‘gc’ method for requesting JVM to run Garbage Collector.
System.gc();

By Using Runtime Class
     A java application can communicate with JVM by using Runtime Object. We can get Runtime Object as follows.
Runtime r = Runtime.getRuntime();
     Once we get Runtime Object we can apply the following methods on that object.
freeMemory() : returns the free memory available in the loop
totalMemory(): returns heap size
gc(): for requesting JVM to run GarbageCollector
E.g
package com.ashok.gc;

import java.util.Date;

public class MyRuntime {
   public static void main(String arg[]) {
      Runtime r = Runtime.getRuntime();
      System.out.println("Total Memory :" +r.totalMemory());
      System.out.println("Free Memory :" +r.freeMemory());
      for (int i = 0; i <= 10000; i++) {
         Date d = new Date();
         d = null;
      }
      System.out.println("Free Memory Before GC :" +r.freeMemory());
      r.gc();
      System.out.println("Free Memory After GC :" +r.freeMemory());
   }
}
Output
Total Memory :253231104
Free Memory :250588664
Free Memory Before GC :250588664
Free Memory After GC :251605720
Note
     gc() method available in the system class is static method but gc() method available in Runtime class is an instance method.
finalization
     Just before destroying any object Garbage Collector always calls finalize() to perform clean up activities. finalize() is available in the Object class which is declared as follows.
protected void finalize() throws Throwable {

}
Case 1
     Garbage Collector always calls finalize() on the Object which is eligible for Garbage Collector and the corresponding class finalize method will be executed.
E.g
package com.ashok.gc;

class MyFinalize {
   public static void main(String arg[]) {
      String s = new String("Waytoeasylearn");
      s = null;
      System.gc();
      System.out.println("End of main method");
   }
   public void finalize() {
      System.out.println("Inside Finalize method");
   }
}
Output
End of main method
     In this case String Object is eligible for G.C and hence String class finalize() method has been executed. In the above program if we are replacing String Object with MyFinalize Object ( MyFinalize s = new MyFinalize();) then MyFinalize class finalize() will be executed. In this case output is
End of main method
Finalize method called
Or
Finalize method called
End of main method
Case 2
     We can call finalize() explicitly in that case it will execute just like a normal method and object won’t be destroyed.
     While executing finalize() method if any exception is uncaught it is simply ignored by the JVM but if we are calling finalize method explicitly and if an exceptions is uncaught then the program will be terminated abnormally.
package com.ashok.gc;

public class MyFinalize {
   public static void main(String arg[]) {
      MyFinalize s = new MyFinalize();
      // s.finalize();
      s = null;
      System.gc();
      System.out.println("End of main method");
   }

   public void finalize() {
      System.out.println("Inside finalize method");
      System.out.println(10 / 0);
   }
}
Output
End of main method
Inside finalize method
     In the above example if we remove comment then it will execute just like a normal method so we will get ArithmeticException.

Case 3
1. Garbage Collector calls finalize() only once on any object i.e it won’t call more than once.
2. While executing finalize() there maybe a chance of object getting reference variable at that time G.C won’t destroy that object after completing finalize()
3. If the same object is eligible for G.C second time with out executing finalize() method G.C will destroy that object.
package com.ashok.gc;

public class MyFinalize {
   static MyFinalize s;
   public static void main(String arg[]) throws InterruptedException {
      MyFinalize f = new MyFinalize();
      System.out.println(f.hashCode());
      f = null;
      System.gc();
      Thread.sleep(4000);
      System.out.println(s.hashCode());
      s = null;
      System.gc();
      Thread.sleep(4000);
      System.out.println("End of main method");
   }

   public void finalize() {
      System.out.println("Inside finalize method");
      s = this;
   }
}
Output
366712642
Inside finalize method
366712642
End of main method
     The behavior of G.C is vendor dependent hence there is no guarantee for the following
1. Whether the G.C follows mark & sweep algorithm or not
2. What exact Algorithm followed by Garbage Collector
3. In which order Garbage Collector destroys Object
4. Whether Garbage destroys all eligible objects or not
5. At what time exactly Garbage Collector will run.

Memory leaks
1. An object which is not using in our application and it is not eligible for GC such type of objects are called "memory leaks".
2. In the case of memory leaks GC also can't do anything the application will be crashed due to memory problems.
3. In our program if memory leaks present then certain point we will get OutOfMemoryException. Hence if an object is no longer required then it's highly recommended to make that object eligible for GC.
4. By using monitoring tools we can identify memory leaks.

No comments:

Post a Comment