Few days back I was arguing with my fellow men that it is not necessary to initialize the instance to null after performing the business logic, however the discussion was ended on nothing.
But after than I did some googling and find the following from sun’s site.
Some object-oriented languages require that you keep track of all the objects you create and that you explicitly destroy them when they are no longer needed. Managing memory explicitly is tedious and error-prone. The Java platform allows you to create as many objects as you want (limited, of course, by what your system can handle), and you don't have to worry about destroying them. The Java runtime environment deletes objects when it determines that they are no longer being used. This process is called garbage collection.
An object is eligible for garbage collection when there are no more references to that object. References that are held in a variable are usually dropped when the variable goes out of scope. Or, you can explicitly drop an object reference by setting the variable to the special value null. Remember that a program can have multiple references to the same object; all references to an object must be dropped before the object is eligible for garbage collection.
The Java runtime environment has a garbage collector that periodically frees the memory used by objects that are no longer referenced. The garbage collector does its job automatically when it determines that the time is right.
Reference: http://java.sun.com/docs/books/tutorial/java/javaOO/usingobject.html
My Observation:
I write a small code to confirm “References that are held in a variable are usually dropped when the variable goes out of scope”
public static void main(String[] args){
{ SayHelloController c= new SayHelloController(); }
try{ System.gc(); }catch (Throwable e) { e.printStackTrace(); }
}
protected void finalize() throws Throwable {
super.finalize();
System.out.println("Finally Called :: ” +this.getClass().getName());
}
Now, In the above case even though variable is out of scope when “System.gc()” was called finalize didn’t called.
So, I change the code little bit
public static void main(String[] args){
{ SayHelloController c= new SayHelloController(); c= null; }
try{ System.gc(); }catch (Throwable e) { e.printStackTrace(); }
}
protected void finalize() throws Throwable {
super.finalize();
System.out.println("Finally Called :: ” +this.getClass().getName());
}
Now, Finalize called.
Well! This doesn’t mean that “References that are held in a variable are usually dropped when the variable goes out of scope” is invalid or is a false statement, because it is also possible that when reference variable is not explicitly referenced to “null”, Garbage Collector may evaluate that either object is valid for to be destroyed, determined on the time basis.
However, after than I realized that it is better to initialize the reference variable with null. But I don’t find it handy to initialize every to null at the end of the method, so I though that there will be a method in every Model Object that will initialize every property with null. Now in my web application I invoke this after doing every thing at the end of the JSP.
Here I am also presenting that code (It has some flaws but it is enough for me).
public abstract class AbstractInitializeEveryPropertyToNull {
public void initializeEveryPropertyToNull() {
Method[] inputBeanMethods= this.getClass().getMethods();
Class[] toRepresentParamType= new Class[1];
Object[] toRepresentEmptyParam= new Object[0];
Object[] toRepresentParam= new Object[1];
java.util.ArrayList<String> availableSetters= new java.util.ArrayList<String>();
for(int i=0; i<inputBeanMethods.length; i++){
String methodName= inputBeanMethods[i].getName();
if(methodName.indexOf("set") == 0)
availableSetters.add(methodName);
}
for(int i=0; i<inputBeanMethods.length; i++){
String getterMethodName= inputBeanMethods[i].getName();
if(getterMethodName.indexOf("get") == 0){
String settMethodName= "set" +getterMethodName.substring(3);
if(!availableSetters.contains(settMethodName))
continue;
toRepresentParamType[0]= inputBeanMethods[i].getReturnType();
Method setterMethod= null;
try {
setterMethod= this.getClass().getMethod(settMethodName,toRepresentParamType);
toRepresentParam[0]= inputBeanMethods[i].invoke(this, toRepresentEmptyParam); // this is a getter method
if(toRepresentParam[0] instanceof AbstractInitializeEveryPropertyToNull)
((AbstractInitializeEveryPropertyToNull)toRepresentParam[0]).initializeEveryPropertyToNull();
toRepresentParam[0]= null; // this is a getter method
setterMethod.invoke(this, toRepresentParam);
}catch (NoSuchMethodException e) { log.info("NoSuchMethodException in " +this.getClass().getName() +".initializeEveryPropertyToNull(): " +settMethodName +" does not exist in " +this.getClass().getName()); }
catch (IllegalAccessException e) { log.error(e); }
catch (InvocationTargetException e) { log.error(e); }
} // if
} // for
} // initializeEveryPropertyToNull
}
6 comments:
nice blog.
Hi!
you are mistaken. Your program tests your assumptions about the finalize method (which are wrong) and not the behavior of the garbage collector.
See also:
http://www.informit.com/articles/article.aspx?p=20527
Best Regards,
Wulf0r
you are wasting your time and your users' time by reflectively null-ing your variables; why should you care about when the memory is reclaimed?
The gc will eventually free the memory; memory is cheap; your time is not and using reflection to null values is an unnecessary performance-degrading operation.
1. System.gc() dosen't start gc.
2. Setting variables to null solves nothing.
3. finalize method dosen't work like you implied. It usally takes at least 2 gc cycles before finalize is called on a dead object, and even then there is no guarantee it will be called. The only guarantee is that it will be called beafore JVM shutts down.
Your testing is horribly flawed and your assumptions are absolutely wrong.
Read the JLS and JVM spec and educate yourself.
I have some explaination,
While writing J2ME program it is highly encouraged to intialize the the instance variable to null because of low memory, therefore, to say "Setting variables to null solves nothing", i think it is not wright.
Well memory is cheap but still we have faced lot of time "OutOfMemoryError" or "Stack out of heap memory" and hence sometimes lot of memory does not solve this problem. And if you are devolping for cloud where you are charged for every CPU cycle and for every byte in memory, then you have to decide either memory or CPU Cycle is more important.
I have never thought about reading JLS or JVM specification, but now I will read it.
Post a Comment