Garbage Collection & Object Class
In Java, we create objects dynamically using new operator. These objects occupy space in heap memory regardless of their scope. Once an object is created in heap,it is retained in memory till there is an associated reference variable. If an object is reference less, then it would not be retained in the memory, it is assumed useless and occupied memory can be reallocated to new objects.
Unlike C++, Java programmers need not write special code to reclaim the on space because Java handles the deallocation process automatically through the garbage collection process. Garbage collection is a process run by a daemon thread called garbage collector. Garbage collector finds the un-referenced objects and reclaim their memory. Unreferenced objects are also called unreachable objects. Unreachable objects are always eligible for garbage collection.
Now the question arises, how to identify the unreachable objects? It can be cleared using the following program and diagrams:
class rect
{
int L,B;
rect (int L1,int B1)
{
L=L1;
B=B1;
}
void show()
{
System.out.println("L ="+L+"B = "+B);
}
}
class gcdemo
{
public static void main(String args[])
{
rect r1=new rect(2,3);
rect r2=new rect(4,5);
rect r3=r1;
r3.show();// L=2 B=3
r1=r2;
r1.show();// L=4 B=5
r3=r1;
r1.show();// L=4 B=5
}
}
In the above program, line 18 and 19 create two objects and two reference variables as shown below:
In line number 20, a new reference variable R3 is created and R1 assigns its reference to R3. However, R1 and R3 refers to the same object as shown below:
In line number 22, R2 assigns its reference to R1. Up to now, no object is unreachable, as shown below:
In line number 24 R1 assigns its reference to R3. Now object having values 2 and 3 becomes unreferenced or unreachable.This object is now eligible for garbage collection.
Before removing from memory, garbage collector calls finalize() method of that object for clean up operation.
Programmer cannot force the garbage collection process to start because it is run by the JVM at random intervals according to the availability of memory in heap.
Java API provide two methods:
These methods are used to send requests to JVM for garbage collection but it guarantees that the garbage collector will run.
Cyclic Dependencies are not considered as reference. For example, if object reference of object y and object y has reference of object x but they both do have any reference on stack directly or indirectly, then they will be eligible garbage collection , as shown below:
Objects x1 and y1 are not eligible for garbage collection, because object x1 is referenced by a reference variable RV from stack and object y1 is referenced from inside object x1.
If you write RV = null, then these objects become unreachable and are eligible for garbage collection.
java.lang.Object (The Universal Class)
Class Object is provided in the java.lang package by Java API. Object class is the root of every class hierarchy. It means that every class is derived internally from Object class directly or indirectly. It consists of the following methods which become the member of every class in Java:
1.protected native Object clone() throws CloneNotSupportedException:
It creates and returns a copy of an object. A class must implement Cloneable interface for using this method, otherwise the compiler shows CloneNotSupportedException. For example:
class rect implements cloneable
{
int L = 10, B = 20;
Rect copy()
{
return(this.clone());
}
void area()
{
System.out.println("Area = "+L*B);
}
}
class cdemo
{
public static void main(String args[])
{
Rect r1=new rect();
r1.area();//Area=200
try
{
rect r2=r1.copy();
}
catch(CloneNotSupportException ex)
{
ex.printStackTrace();
}
r2.area(); // Area=200
}
}
- In this program, class Rect contains methods copy() and area(). Its copy(). method calls method clone() to create a new copy of the object and returns to the calling method.
- Note that class Rect implements Cloneable interface to use clone() method inside the member functions.
- In line number 21, R1 invokes copy0 method to create a new object and assigns its reference to R2.
The copy() method must be called with in the try block because clone() method can throw checked exception: CloneNotSupportedException.
2. public boolean equals (Object obj)
The equals() method of Object class checks the reference equality of two objects, like==(equality) operator. It does not match the content of objects. This method can be used for non-null object references only, for example:
class rect
{
int L,B;
rect(int L1,int B1)
{
L=L1;
B=B1;
}
void show()
{
System.out.println("L ="+ L +"B="+B);
}
}
class demo
{
public static void main(String args[])
{
rect r1=new rect(2,3);
r1.show();// L=2 B=3
rect r2=new rect(2,3);
r2.show();
System.out.println("r1.equals(r2):"+r1.equals(r2));
System.out.println("r1==r2:"+r1==r2);
rect r3=r2;
System.out.println("r3.equals(r2):"+r3.equals(r2));
System.out.println("r3==r2:"+r3==r2);
}
}
Output
R1.equals(R2):false
R1==R2.:false
R3.equals(R2):true
R3==R2:true
Explanation
In this program, reference variables R1 and R2 refer to different objects, so R1.equals(R2) evaluates to false, where as R2 and R3 reference variable refer the same object, so R2.equals(R3) evaluated to true.
The equality operator (==) also compares the refence equality like equals() method. To use equals() method to compare the contents to two String objects.
The following program demonstrates the overriding of equals() method to change its default behaviour provided in java.lang.Object class.
3. public String toString():
This method returns a string representation of an object. It returns a String object consisting of name of the class, the ‘at sign’ character '@' and the unsigned hexadecimal representation of the hash code of the object. The toString() method consists the statement as written below:
getClass().getName() + '@' + Integer.to HexString(hashCode());
class rect
{
int L=10,B=20;
}
class demo
{
public static void main(String args[])
{
rect r1=new rect();
System.out.println(r1.toString());
}
}
Output
Rect@addbj1
Explanation
The above output is not quite meaningful. The behaviour of toString() method can be improved by overriding it in user defined classes, as shown in the program below:
class rect
{
int L=10,B=20;
public String toString()
{
return("Length="+L+"Breadth="+B);
}
}
class demo
{
public static void main(String args[])
{
rect r1=new rect();
System.out.println(r1.toString());
}
}
Output
Length=10 Breadth = 20
Explaination
In this program, class Rect overrides toString() method, to return the value of L and B In the line number 14, R1 invokes toString method, which shows more informative output on the screen.
4. public final native Class <?>getClass()
The getClass() method returns the runtime class of the invoking object. It returns the object of java.lang.Class. By using the methods provided by java.lang.Class. you can get information about the construction fields, method etc. of any class, whether it is user defined class or library class. For example
5. protected void finalize() throws Throwable
The finalize() method is the member of java.lang. Object class. The body of this method is empty, i.e it does nothing when called by JVM. Now to questions rises:
Question (1):When it is called?
Question (2):If it does nothing, then what is the use of this method?
Answer (1):This method is called immediately before the destruction of a object by the garbage collection process run by the JVM.
Answer (2):It is a fact that actual function body of the finalize() method in Object class is empty, but it can be overridden by the derived class to per-form clean up actions before the object is irrevocably discarded. For example, an object copy the contents of one file to another, the finalize() methoden be overridden to close the files to break up the connections before they are permanently discarded.
If an uncaught exception is thrown by the finalize() method, the exception is ignored and finalization of the object terminates.
The finalize() method is never invoked more than once by the JVM for any given object. The following program shows overriding of finalize() method to close the file opened by the object for reading and writing operation
import java.io.*;
public class Finalized
{
FileInputStream read;
FileOutputStream Write;
void copyText() throws FileNotFoundException,IOException
{
int c;
read=new FileInputStream("real.txt");
write=new FileOutputStream("real2.txt");
while((c=read.read()!=-1))
{
write.write(c);
}
System.out.println("File Copied....");
}
protected void finalize()throws Throwable
{
read.close();
write.close();
}
public static void main(String[] args)
{
try
{
new Finalized().copyText();
System.gc();
}
catch(FileNotFoundException ex)
{
ex.printStackTrace();
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
Output
File Copied
In above program, finalized method is overridden to close the files opened for reading and writing operations.
6. wait() and notify()
wait() and notify() methods are also members of java.lang. Object class. These method are discussed in detail in Multitasking/Threads chapter in this book.