Yes.
Create a class based static instance counter that is synchronous
Up it by one in the class method(s) that instantiate..
Then u will have to override the dispose method to decrement instance counter..
UPDATE
Here is a nebulous class.. that can be used to track some things...
package myclasses;
import java.util.Vector;
public class ClassA {
private static int iCountInstances = 0;
private static int iCountCleanups = 0;
private static int iCountGCFinalize = 0;
private String m_str1 = null;
private Vector m_vct1 = null;
public ClassA() {
// bump the instance count
incrementCountInstance();
}
private static synchronized void incrementCountInstance() {
iCountInstances++;
}
private static synchronized void incrementCountCleanup() {
iCountCleanups++;
}
private static synchronized void incrementGCFinalize() {
iCountGCFinalize++;
}
/**
* reportOut - you can change this up on how ever you like
*
* an in control app in a perfect world will have all three counts THE SAME after a final
* GC and right before exist.
*
* The True number of 'active' classes in an app is going to be
* ICountInstances - iCountGCFinalize.
*
* The idea here is that if GC did not dispose of it.. its still in memory.. and still
* active.. even if your app thinks its no longer using it...
*
* @return
*/
public static String reportOut() {
return "ClassA Counts: incnt:" + ClassA.iCountInstances +", clncnt:" + ClassA.iCountCleanups + ", gccnt:" + ClassA.iCountGCFinalize;
}
public void cleanup() {
//
// ok.. initialize all member variables here
// do not worry about what other object refereneces this guy
// you only care about what you have as member variables.
// you only de-refrence what you point to ..
// if every class took care of what it referenced.. then all is well.
// so.. clean up your object and help GC ...
this.setM_str1(null);
this.getM_vct1().removeAllElements();
ClassA.incrementCountCleanup(); // Increment the cleanup count..
//
// feel free to write to a logger reporting out that programmer has cleaned up this instance..
//
}
@Override
protected void finalize() throws Throwable
{
// Incrementing means GC determined this guy is truly an Object Orphan and has been
// completely de-referenced.
ClassA.incrementGCFinalize();
//
// feel free to write to a logger reporting out that GC is removing this instance..
//
}
public String getM_str1() {
return m_str1;
}
public void setM_str1(String m_str1) {
this.m_str1 = m_str1;
}
public void setM_vct1(Vector m_vct1) {
this.m_vct1 = m_vct1;
}
public Vector getM_vct1() {
return m_vct1;
}
}
Here is another class that can be made to help report out whats going on during execution.. etc..
package myclasses;
public final class CheckCounts {
// No create instance allowed..
private CheckCounts() {
}
/**
* Report out on interesting counts...
*/
public static void reportOut() {
/// Add all the reportouts here..
System.out.println(ClassA.reportOut());
}
}
You can get fancy with this and create a background thread monitor that simply reports out stats on the classes you want to track.. and have it write to a logger every 30 seconds or so..
Notice I count up everything. You can use math to see how effective your code is at cleaning up after itself.. When you clean up an object.. you want to dereference what that objected pointed to and clear out any lists, arrays, hashmaps, etc. Be careful though, dont go crazy, and start cleaning up objects that live in a Vector of your class - just clean up the vector itself...
Give it a try.. its easy to implement.. and it may help you see whats going on in a runtime env vs what you think is happening just by looking at your code..