天天看点

Java 垃圾回收规则

Rules available in this category:

  1. Do_not_remove_listeners_inside_finalize
  2. Avoid_using_synchronized_code_within_finalizers
  3. Avoid_static_collections
  4. Always_call_reset
  5. Provide_protected_access_to_finalizers
  6. Use_array_of_long_instead_of_Dates
  7. Do_not_call_finalize_directly
  8. Always_reuse_calls_to_java_awt_Graphics_getClipBounds_method
  9. Avoid_calling_java_lang_Runtime_runFinalization
  10. Avoid_explicitly_calling_gc
  11. Avoid_empty_finalizers
  12. Always_call_super_finalize
  13. Always_call_super_finalize_in_finally_block

Rule 1: Do_not_remove_listeners_inside_finalize

Severity: 

High

Rule: 

Avoid removing listeners inside finalize method.

Reason:  Usage Example: 
package com.rule;

import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

public class Do_not_remove_listeners_inside_finalize_violation implements PropertyChangeListener
{
	Component comp;
	
	public Do_not_remove_listeners_inside_finalize_violation(Component c)
	{
		comp = c;
		comp.addPropertyChangeListener(this);
	}
	
	protected void finalize() throws Throwable
	{
		comp.removePropertyChangeListener(this);		// VIOLATION
		super.finalize();
	}

	public void propertyChange(PropertyChangeEvent evt)
	{
	}
}      
Should be written as:
Remove the listeners when they are no longer required, may be from a seperate method used for cleanup.      
Reference: 

http://www-106.ibm.com/developerworks/java/library/j-jtctips/j-jtc0319a.html

Rule 2: Avoid_using_synchronized_code_within_finalizers

Avoid using synchronized code within finalizers(finalize method).

package com.rule;
public class Avoid_using_synchronized_code_within_finalizers_violation 
{
	public void finalize()
	{
		syncMethod();             // Violation
	}
	public synchronized void syncMethod()
	{
		//...
	}
}      
Avoid using synchronized code inside finalize method.      

http://www.cs.arizona.edu/sumatra/hallofshame/monitor-finalizer.html

Rule 3: Avoid_static_collections

Disallows the use of static collection fields.

public class Avoid_static_collections_violation
	{
	    public static Vector vector = new Vector (5);	// VIOLATION

	    public static void addToVector (Object o) 
	    {
		    vector.add(o);
	    }

	}      
public class Avoid_static_collections_correction 
	{
	    public Vector vector = new Vector (5);	// CORRECTION


	    public static void addToVector (Object o) 
	    {
		    vector.add(o);
	    }

	}      

Java Performance tunning by Jack Shirazi

Rule 4: Always_call_reset

If you are using ObjectStream, do remember to call reset() method as ObjectStream classes keep a reference to all objects written or read until the `reset()' method is called and hence the objects can not be garbage collected.

package com.rule;
import java.io.ObjectOutputStream;
import java.io.IOException;

class Always_call_reset_violation
{
	public void writeToStream(ObjectOutputStream os, String s)throws IOException  
	{
		os.writeObject (s);// VIOLATION
	}
}      
package com.rule;
import java.io.ObjectOutputStream;
import java.io.IOException;

class Always_call_reset_correction
{
   public void writeToStream(ObjectOutputStream os, String s)throws IOException
   {
   		os.writeObject (s);
   		os.reset();			  // CORRECTION
   }
}      

http://developer.java.sun.com/servlet/PrintPageServlet?url=http%3A//developer.java.sun.com/developer/technicalArticles/ALT/sockets/

Rule 5: Provide_protected_access_to_finalizers

Provide protected access to finalize method.

package com.rule;

public class Provide_protected_access_to_finalizers_violation 
{
	public void finalize() //Violation
	{
	}
}      
package com.rule;

public class Provide_protected_access_to_finalizers_corection 
{
	protected void finalize() //Correction
	{
	}
}      

Reference not available.

Rule 6: Use_array_of_long_instead_of_Dates

Avoid using array of 'Date' objects, use an array of "long" instead.

package com.rule;
import java.util.Date;
class Use_array_of_long_instead_of_Dates_violation
{
	private final int size = 10;
	private Date d[] = new Date[size];		// VIOLATION

	public void method()
	{
		if(d != null)
		{
			d = null;
		}
	}

}      
package com.rule;
class Use_array_of_long_instead_of_Dates_correction
{
	private final int size = 10;
	private long d[] = new long[size];		// CORRECTION

	public void method()
	{
		if(d != null)
		{
			d = null;
		}
	}
}      

Reference Not Available.

Rule 7: Do_not_call_finalize_directly

Medium

The finalize method is called by garbage collector and it should not be called directly

package com.rule;

class Do_not_call_finalize_directly_violation
{
	static void method(Do_not_call_finalize_directly_violation obj) throws Throwable
	{
		obj.finalize();
	}
	
	protected void finalize() throws Throwable
	{
		super.finalize();
	}

}      
package com.rule;

class Do_not_call_finalize_directly_violation
{
	static void method(Do_not_call_finalize_directly_violation obj) throws Throwable
	{
		//obj.finalize();
	}
	
	protected void finalize() throws Throwable
	{
		super.finalize();
	}

}      

http://www.ambysoft.com/javaCodingStandards.pdf

Rule 8: Always_reuse_calls_to_java_awt_Graphics_getClipBounds_method

The getClipBounds method always returns a new rectangle, thereby allocating more memory on every call.

import java.awt.Graphics;

public class MyClass
{

	public void paint(Graphics g)  // VIOLATION
	{
      	  int firstColLine = g.getClipBounds().x;
              int lastColLine = g.getClipBounds().x + g.getClipBounds().width;
    	}

}      
import java.awt.Graphics;
import java.awt.Rectangle;

public class MyClass
{

	public void paint(Graphics g)  // VIOLATION
	{
		Rectangle rec = g.getClipBounds(); // CORRECTION
		int firstColLine = rec.x; // CORRECTION
		int lastColLine = rec.x + rec.width; // CORRECTION
    	}

}      

No references available.

Rule 9: Avoid_calling_java_lang_Runtime_runFinalization

One should not invoke garbage collection manually.

public class NoRunFinalization
{
	public static void main( String[] args)  
	{
		for ( int i = 0; i < args.length; ++i ) 
		{
			System.out.println( args[ i ] );
		}
		Runtime.getRuntime().runFinalization();
	}
}      
public class NoRunFinalization
{
	public static void main( String[] args)  
	{
		for ( int i = 0; i < args.length; ++i ) 
		{
			System.out.println( args[ i ] );
		}
	}
}      

Rule 10: Avoid_explicitly_calling_gc

Avoid explicitly calling System.gc().

package com.rule;

class Avoid_explicitly_calling_gc
{
	public void print()
	{
		Object[] oa = getObjects();
		process(oa);
		System.gc();		// Violation.
	}
}      

Rule 11: Avoid_empty_finalizers

Avoid empty finalize method.

package com.rule;

public class Avoid_empty_finalizers_violation
{
	public void finalize() // Violation
	{

	}
}      
package com.rule;

public class Avoid_empty_finalizers_correction
{
	public void finalize() // Correction
	{
		try
		{
			super.finalize();
		}
		catch (Throwable e)
		{
			// ...
		}
	}
}      

Rule 12: Always_call_super_finalize

If you are over writing finalize method then make sure that it calls super.finalize() method.

package com.rule;

public class Always_call_super_finalize_violation
{
	protected void finalize () throws Throwable		 // VIOLATION
	{  
		//...
	}
}      
package com.rule;

class Always_call_super_finalize_correction
{
	protected void finalize () throws Throwable
	{
	   super.finalize();	 // CORRECTION
	}
}      

http://www.javaworld.com/javaworld/jw-01-1999/jw-01-object_p.html

Rule 13: Always_call_super_finalize_in_finally_block

If there is a try block in the finalize method, super.finalize() should be called from the finally block.

public class AlwaysCall_super_finalize_inFinallyBlock 
{
    protected void finalize () throws Throwable 
    {
       try 
       {
       } 
       catch (Exception e) 
       {
       } 
       finally // VIOLATION, 'super.finalize()' is not invoked
       {  
           return;
       }
    }


    public class AlwaysCall_super_finalize_inFinallyBlockMember 
    {
	protected void finalize() 
	{
    	try 
    	{
            close();
	    super.finalize();
	} catch (Exception e) 
	{ 
	//VIOLATION, missing a "finally" block that invokes 'super.finalize()'
        //Note that if 'close()' throws an exception, 'super.finalize()' would not be invoked
    	}
    }
}      
public class AlwaysCall_super_finalize_inFinallyBlock 
{
    protected void finalize () throws Throwable 
    {
       try 
       {
       } 
       catch (Exception e) 
       {
       } 
       finally // VIOLATION, 'super.finalize()' is not invoked
       {  
           super.finalize(); // CORRECTION
       }
    }


    public class AlwaysCall_super_finalize_inFinallyBlockMember 
    {
	protected void finalize() 
	{
    	try 
    	{
            close();
	} catch (Exception e) 
	{ 
    	}
    	finally
    	{
    	    super.finalize(); // CORRECTION
    	}
    		    
    }
}      

"The Java Programming Language, Second Edition", by Ken Arnold and James Gosling. Page 49.  

原文引自:http://www.appperfect.com/support/java-coding-rules/garbagecollection.html