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

Reference from input method prevents garbage collection on client component

    • 1.2.2
    • x86
    • windows_nt

      Report from ###@###.###:

      // file: TrivialApplication.java

      import java.awt.*;
      import java.awt.event.*;
      import com.sun.java.swing.*;

      public class TrivialApplication {

          public static void main(String args[])
          {
              JFrame theFrame = new JFrame("ContainerPanel test");
              theFrame.setSize(100, 100);
              ContainerPanel cp = new ContainerPanel();
              theFrame.getContentPane().add(cp);
              theFrame.show();
              try {
                  Thread.currentThread().sleep(10000);
              }
              catch (InterruptedException e) {}
              System.out.println("Removing ContainerPanel");
              theFrame.getContentPane().remove(cp);
              cp.remove(cp.getComponent(0));
              cp = null; // lose our reference to it.
              theFrame.getContentPane().requestFocus();
              theFrame.validate();
              theFrame.repaint();
              System.gc();
              try {
                  Thread.currentThread().sleep(10000);
              }
              catch (InterruptedException e) {}
              System.exit(0);
          }

      }

      // file: ContainerPanel.java

      import java.awt.*;
      import java.awt.event.*;
      import com.sun.java.swing.*;

      public class ContainerPanel extends JPanel {
             public JButton testButton = new JButton("foo");

             public ContainerPanel() {
                  setLayout (new BorderLayout());
                  add("Center",testButton);
                  testButton.addActionListener(new TestButtonListener());
             }

             // The action listener is an inner class
             class TestButtonListener implements ActionListener {
                  public void actionPerformed (ActionEvent e) {
                       // Do something, it really doesn't matter what
                  }
             }
      }

      Note that I keep main() into another class so that there won't be any
      extraneous references to ContainerPanel's class on the stack. Possibly
      paranoid....

      I then ran this program under JDK 1.2beta4 with heap profiling turned on:

      java -cp AppClasses.jar -Xhprof:file=dump.hprof,format=b TrivialApplication

      I took a memory checkpoint (ctrl-break on Windows) during the second 10
      second pause in the code, and ran the output through HAT.
      <http://developer.javasoft.com/developer/earlyAccess/hat/>

      Here's what I found:

      --> java.awt.FocusManager@0xa0acc001 (8 bytes) (field focusOwner:)
      --> com.sun.java.swing.JButton@0xb0e0c001 (328 bytes) (field listenerList:)

      and:

      --> sun.awt.windows.WInputMethod@0x60c7c001 (24 bytes) (field clientComponent:)
      --> com.sun.java.swing.JButton@0xb0e0c001 (328 bytes) (field listenerList:)

      So it looks like, even though it's been removed from the JFrame (by virtue
      of its parent ContainerPanel being removed), the JButton still has focus.
      And, indeed inserting the line:

              theFrame.getContentPane().requestFocus();

      right before the call to theFrame.validate() gets rid of the FocusManager's
      reference to the JButton. I have thus far been unable to get rid of the
      WInputMethod references, though. Anyone have any ideas on this?


      John Brewer
      Jera Design

            sherman Xueming Shen
            nlindenbsunw Norbert Lindenberg (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: