Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4220231

(refs) Strange behavior of weak refs and finalization

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3
    • Resolution: Not an Issue
    • Affects Version/s: 1.2.0
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description



      Name: dbT83986 Date: 03/14/99


      Designing a workaround to swing's bugs, I found another one...

      In the following, the weak reference is not cleared as supposed.

      Using HAT 1.0.3, (Heap analysis tool), you will see that
      some Finalizer object keeps a ref on the object cleared
      at the line marked "CRITICAL POINT".


      You can make several test with this code:
      1-different reference type (the phantom one is cleared even
        before we clear the "al" variable!)
      2-different reference queue analysis mode
      3-adding or not a finalize() method to the cleared object (SomeAL)

      Steps:

      1-Compile the code as is (!).
      2-Run the program.
      3-As the frame appear, click on the button to verify
      that an underlying listener is there (it should be until
      the CRITICAL POINT is passed).
      You may click more than once.
      4-As the critical point is passed, click again to verify again.
      You may click more than once.
      5-You should see the bug: the ref is not cleared as it should be.
      But if I remove the finalize() method, it is!

      6-Try steps 2 to 5 with the phantom reference variant.
      Now the ref is cleared too soon!

      ------------
      Details:

      java full version "JDK-1.2-V"

      java version "1.2"
      Classic VM (build JDK-1.2-V, green threads, nojit)

      Under solaris 2.6

      //==================================================================
      // NAME: ALWeakRef.java
      //==================================================================

      //
      // PACKAGE:
      //


      //
      // IMPORTS:
      //
      import java.lang.*;
      import java.awt.*;
      import java.awt.event.*;
      import java.lang.ref.*;


      /***************
      */
      //public class ALWeakRef extends PhantomReference implements ActionListener
      public class ALWeakRef extends WeakReference implements ActionListener
      //public class ALWeakRef extends SoftReference implements ActionListener
      {
      WeakReference src;

      public ALWeakRef(ActionListener al, ReferenceQueue rq, Object eventSource)
      {
      super(al,rq);
      src = new WeakReference(eventSource);

      System.out.println("ALWeakRef construction.");
      }

      public void actionPerformed(ActionEvent ae)
      {
      System.out.println(""+this+" actionPerformed");
      Object obj = get();
      System.out.println(""+this+" OBJ="+obj);
      if(obj!=null && obj instanceof ActionListener)
      ((ActionListener)obj).actionPerformed(ae);
      else
      System.out.println(""+this+" NO REAL AL");
      }

      public Object getEventSrc()
      {
      System.out.println(""+this+" getEventSrc");
      return src.get();
      }

      //------------------

      public void clear()
      {
      System.out.println(""+this+" clear");
      super.clear();
      }

      public Object get()
      {
      System.out.println(""+this+" get");
      return super.get();
      }

      public boolean isEnqueued()
      {
      System.out.println(""+this+" isEnqueued");
      return super.isEnqueued();
      }

      public boolean enqueue()
      {
      System.out.println(""+this+" enqueue");
      return super.enqueue();
      }

      //------------------


      public static void main(String args[]) throws Exception
      {
      Frame f = new Frame();
      Button b = new Button("go");

      f.add(b);
      f.setSize(400,300);
      f.setVisible(true);

      ReferenceQueue rq = new ReferenceQueue();
      ActionListener al = new SomeAL();
      ALWeakRef alwr = new ALWeakRef(al,rq,b);
      b.addActionListener(alwr);



      System.out.println("sleep 3000");
      Thread.sleep(3000);

      //CRITICAL POINT:
      System.out.println("CRITICAL POINT: al=null");
      al = null;
      //--------------

      System.gc(); //give a hand to gc..
      System.runFinalization();


      while(true)
      {
      Reference ref = rq.remove(); //test 1
      //Reference ref = rq.remove(500); //test 2
      //Reference ref = rq.poll(); //test 3

      if(ref!=null)
      {
      ref.clear();
      System.out.println("ref queue contains: "+ref);
      ALWeakRef alwr2 = (ALWeakRef)ref;
      System.out.println(" src is: "+alwr2.getEventSrc());
      Button b2 = (Button)alwr2.getEventSrc();
      b2.removeActionListener(alwr2);

      //rq.remove(); //test 3 (with rq.poll() only)

      }
      else
      {
      System.out.println("ref queue is empty(), sleep 500");
      Thread.sleep(500);
      }
      ref = null;
      }
      }

      }//end public class ALWeakRef


      class SomeAL implements ActionListener
      {
      public void actionPerformed(ActionEvent ae)
      {
      System.out.println(" Real AL actionPerformed "+ae);
      }


      //the finalizer presence causes a bug!!!
      ///*
      protected void finalize() throws Throwable
      {
      System.out.println(" Real AL finalized");
      }
      //*/
      }
      (Review ID: 55344)
      ======================================================================

        Attachments

          Activity

            People

            Assignee:
            mr Mark Reinhold
            Reporter:
            dblairsunw Dave Blair (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: