Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Compliant Solution (prevent garbage collection)

Wiki MarkupThis compliant solution takes into account the garbage collection issue described above. A class is not garbage collected until the {{ClassLoader}} object used to load it becomes eligible for garbage collection. An easier scheme to prevent the garbage collection is to ensure that there is a direct or indirect reference from a live thread to the singleton object that needs to be preserved. This compliant solution demonstrates this method (based on \[[Patterns 02|AA. Java References#Patterns 02]\]). that needs to be preserved. This compliant solution demonstrates this method.

Code Block
bgColor#ccccff
{
  MySingleton ms1 = MySingleton.getInstance();
  ObjectPreserver.preserveObject(ms1);
  // ... 
}

MySingleton ms2 = (MySingleton) ObjectPreserver.getObject(); 

Wiki Markup
The {{ObjectPreserver}} class (based on \[[Patterns 02|AA. Java References#Patterns 02]\]) is shown below:

Code Block
public class ObjectPreserver implements Runnable {
  private static ObjectPreserver lifeLine = new ObjectPreserver();
  
  // Neither this class, nor HashSet will be garbage collected.
  // References from HashSet to other objects will also exhibit this property
  private static HashMap<Integer,Object> protectedMap = new HashMap<Integer,Object>();
  
  private ObjectPreserver() {
    new Thread(this).start();  // keeps the reference alive  
  }
 
  public synchronized void run(){
    try {
      wait();
    } catch(InterruptedException e) { /* Forward to handler */ }
  }

  // Objects passed to this method will be preserved until
  // the unpreserveObject method is called
  public static void preserveObject(Object obj) {    
    protectedMap.put(0, obj);  
  }
  
  // Returns the same instance every time
  public static Object getObject() {
    return protectedMap.get(0);	  
  }
  
  // Unprotect the objects so that they can be garbage collected
  public static void unpreserveObject() {
    protectedMap.remove(0);
  }
}

...