Dear reader,
I am writing a very common use case here: Counting number of objects which are there in HEAP memory.
This is basically an interview question: how to count number of objects created for a class.
Giving a very basic example below:
=================
public class MySerialization1 {
static int counter; //Defined a counter for this class
static String className="MySerialization1";
public MySerialization1() {
synchronized(MySerialization.class) { //making the counter thread safe
counter++;
}
}
public static void main(String args[]) throws Exception {
MySerialization1 oc = new MySerialization1();
MySerialization1 od = new MySerialization1();
MySerialization1 oe = new MySerialization1();
MySerialization1 of = new MySerialization1();
MySerialization1 og = new MySerialization1();
System.out.println("Total object count: "+counter);
Object ob=Class.forName(className).newInstance(); //Creating object using Class.forName();
System.out.println("Total object count after Class.forName().newInstance(): "+counter);
og.makeNull(); //Decrease the counter value
og=null; //Make object null
System.out.println("Total object count after null: "+counter);
}
private static void makeNull() {
synchronized(MySerialization.class) {
counter--;
}
}
}
//Output:
Total object count: 5
Total object count after Class.forName().newInstance(): 6
Total object count after null: 5
===================
Now, lets tweak little bit. When you serialize, you will have an object. What if you de-serialize here,
since constructor didn't get invoked at de-serialization time(assuming no inheritance here), you will have
the same count of object. I mean see below example:
===================
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class MySerialization implements Serializable {
private static final long serialVersionUID = 1L;
static String className="MySerialization";
static int counter;
public MySerialization(){
synchronized(MySerialization.class) {
counter++;
}
}
public static void main(String[] args) throws Exception {
MySerialization object=new MySerialization();
System.out.println("Object is: "+object);
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("output.out"));
out.writeObject(object);
System.out.println("Object is saved using Serialization");
ObjectInputStream in=new ObjectInputStream(new FileInputStream("output.out"));
MySerialization deserialObject=(MySerialization)(in.readObject());
System.out.println("Object is read using De-Serialization");
System.out.println("Object is: "+deserialObject);
System.out.println("Total object count after deserialization: "+counter);
Object tempObj=Class.forName(className).newInstance();
System.out.println("Total object count after Class.forName().newInstance(): "+counter);
}
//Comment the below method and then see the output again, This is read internally
//while de-serializing object by JVM.
/*
private Object readResolve(){
return new MySerialization();
}
*/
}
//Output:
Object is: MySerialization@1c4bd0
Object is saved using Serialization
Object is read using De-Serialization
Object is: MySerialization@1c68b0
Total object count after deserialization: 1
Total object count after Class.forName().newInstance(): 2
NOTE: If you see the output, after de-serialization too, count is only 1. Count is increased to "2"
because of Class.forName().newInstance().
Now un-comment the comment line, having method "readResolve()" and then run the same program,
below is the output:
//Output:
Object is: MySerialization@1c4bd0
Object is saved using Serialization
Object is read using De-Serialization
Object is: MySerialization@1c68c8
Total object count after deserialization: 2
Total object count after Class.forName().newInstance(): 3
NOTE: See the difference. When Java De-Serializes a saved object, it checks whether "readResolve()"
method is re-defined in Serializable class or no. You can use "public" access specifier too in place
of "private". If re-defined, it return the object from there. Since constructor again gets called,
Counter is increased.
The same logic we use in SingletonPattern too, where even after De-Serialization, we need the same
old object (I mean only one object) else De-serialization creates a new/converted one which violates
Singleton Pattern fundamental.
NOTE: A more sophisticated program which will show count of Objects of each class used in Program will be written
later, as I have not written as of now.
Like if we use Thread, StringBuffer, HashMap, List etc in our program and then there should be a method to
display ObjectStatistics for each class used in program. You can use Inner class and put a counter there.
I will write later.
--------------------------------END--------------------------------
Wednesday, March 28, 2012
Counting number of Objects in Java
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment