JDK-4180832 : Reference from input method prevents garbage collection on client component
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt:i18n
  • Affected Version: 1.2.0
  • Priority: P1
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1998-10-13
  • Updated: 2013-11-01
  • Resolved: 1999-01-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.2.2 1.2.2Fixed
Related Reports
Relates :  
Description
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

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.2.2 FIXED IN: 1.2.2 INTEGRATED IN: 1.2.2
14-06-2004

SUGGESTED FIX *** /tmp/geta6547 Fri Jan 8 16:56:49 1999 --- InputContext.java Fri Jan 8 11:10:13 1999 *************** *** 299,304 **** --- 299,308 ---- inputMethod.removeNotify(); currentClientComponent = null; } + + if (inputMethod instanceof InputMethodAdapter + && ((InputMethodAdapter) inputMethod).getClientComponent() == client) + ((InputMethodAdapter) inputMethod).setClientComponent(null); } /** *** /tmp/geta6554 Fri Jan 8 16:57:11 1999 --- WInputMethod.java Fri Jan 8 11:28:08 1999 *************** *** 244,249 **** --- 244,250 ---- */ public void removeNotify() { endCompositionNative(context, DISCARD_INPUT); + target = null; } /**
11-06-2004

EVALUATION Need to call setClientComponent(null) from sun.awt.im.InputContext.removeNotify(). Additional steps may be needed to completely unlink the window. norbert.lindenberg@Eng 1998-12-04 WInputMethod.target has to be set to null in removeNotify(). masayoshi.okutsu@Eng 1999-01-07
04-12-1998