Topics:

  1. Introduction
  2. The ways to make an object eligible for Garbage Collector
  3. The methods to request JVM to run Garbage Collector
  4. finalization

Introduction

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“.

The 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
Nullifying the reference Variable
If an object is no longer required assign null to all its reference variables.
Example:

Supplier s1 = new Supplier();
Supplier s2 = new Supplier();
//No Object eligible for Garbage Collector
s1 = null;
//One Object eligible for Garbage Collector
s2 = null;
//Both Objects eligible for Garbage Collector
<strong>Reassigning the reference Variable</strong>
Supplier s1 = new Supplier();
Supplier s2 = new Supplier();
//No Object eligible for Garbage Collector
s1 = s2;
//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
Example1:

class Test{
public static void main(String arg[]){
  m1();
  //Both Objects eligible for Garbage Collector
}
public static void m1(){
  Supplier s1 = new Supplier();
  Supplier s2 = new Supplier();
 }
}

Example2:

class Test{
public static void main(String arg[]){
  Supplier s=m1();
//One Object eligible for Garbage Collector
}
public static Supplier m1(){
  Supplier s1 = new Supplier();
  Supplier s2 = new Supplier();
  return s1;
 }
}

Example3:

class Test{
public static void main(String arg[]){
  m1();
//Both Objects eligible for Garbage Collector
}
public static Supplier m1(){
  Supplier s1 = new Supplier();
  Supplier s2 = new Supplier();
  return s1;
 }
}

The Island of Isolation

Example:

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 Object 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

Example:

package com.java2learn.gc;
import java.util.Date;
public class RuntimeDemo {

	public static void main(String[] args) {
		Runtime r = Runtime.getRuntime();
		System.out.println(r.totalMemory());
		System.out.println(r.freeMemory());
		for (int i = 0; i <= 10000; i++) {
			Date d = new Date();
			d = null;
		}
		System.out.println(r.freeMemory());
		r.gc();
		System.out.println(r.freeMemory());
	}
}

Note: gc() method available in the system class is static method but gc() method available in Runtime class is an instance method.

finalization

4)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{
}
case1: Garbage Collector always calls finalize() on the Object which is eligible for Garbage Collector and the corresponding class finalize method will be executed.
Example:

package com.java2learn.gc;
public class Test {
	public static void main(String arg[]) {
		String s = new String("Java2learn");
		// Test s = new Test();
		s = null;
		System.gc();
		System.out.println("end of main method");
	}

	public void finalize() {
		System.out.println("finalize method called");
	}
}

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 Test Object then Test class finalize() will be executed.

In this case O/P is

end of main method
finalize method called
or
finalize method called
end of main method

case2: 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.
Example:

package com.java2learn.gc;
public class Test {
	public static void main(String arg[]) {
		
		Test s = new Test();
		s = null;
		System.gc();
		System.out.println("end of main method");
	}

	public void finalize() {
		System.out.println("finalize method called");
		System.out.println(10/0);
	}
}

Output:
end of main method
finalize method called

case3:

  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.

Example: