-
Bug
-
Resolution: Fixed
-
P4
-
1.0.1, 1.3.0, 1.3.1
-
03
-
generic, x86, sparc
-
generic, solaris_2.6, windows_nt
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2035362 | 1.4.0 | Scott Violet | P4 | Resolved | Fixed | beta |
Name: sl110371 Date: 07/12/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
/*
Bug 4232051 is marked as closed, but this test program shows
that it's still a problem. When I roll over a button it pops
up a tool tip. This button won't get garbage collected until
another button's tool tip is shown.
Run this program. The "New Objects" button will place a new
button in the main window, freeing the previous button for
garbage collection. Pressing the "GC" button will collect
the garbage, and print out the name of any button it cleans
up.
If you roll over a button to pop up its tool tip, then
replace it with a new button, it won't get garbage collected
until the new button's tool tip shows.
This happens under Metal, but not under the Motif or Windows
L&Fs. I haven't tried any others. I reproduced this under
Windows. While I suspect it's cross platform, I didn't try
it on any other platforms.
*/
import java.lang.ref.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class ToolTipLeak extends JPanel
{
private static ReferenceQueue myQueue = new ReferenceQueue();
private Thread myPoll = new Thread(new Poller());
private HashSet myHash = new HashSet();
private JComponent myPrevComp;
public static void main(String[] args)
{
JFrame mf = new JFrame("Memory Leak in Tool Tip");
WindowListener wl = new WindowAdapter()
{
public void windowClosing(WindowEvent evt) { System.exit(0); }
};
mf.addWindowListener(wl);
mf.setBounds(10, 10, 400, 300);
System.out.println("Java version " + System.getProperty("java.version"));
mf.getContentPane().add(new ToolTipLeak(), BorderLayout.CENTER);
mf.show();
}
ToolTipLeak()
{
super(new BorderLayout());
// setLookAndFeel(); // put this line in to make bug go away.
JPanel controlPanel = makeControlPanel();
add(controlPanel, BorderLayout.SOUTH);
myPoll.start();
}
private JPanel makeControlPanel()
{
JPanel cPanel = new JPanel(new GridLayout(1, 0));
JButton newBtn = new JButton("New Objects");
JButton gcBtn = new JButton("GC");
cPanel.add(newBtn);
cPanel.add(gcBtn);
newBtn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
createNew();
}
});
gcBtn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
System.gc();
}
});
return cPanel;
}
private static int itr = 0;
public void createNew()
{
JButton b1 = makeBtn("Button " + itr);
b1.setToolTipText(b1.getText());
if (myPrevComp != null)
remove(myPrevComp);
myPrevComp = b1;
add(b1, BorderLayout.CENTER);
revalidate();
itr++;
}
JButton makeBtn(String name)
{
JButton btn = new TTButton(name);
addWeakRef(btn, name);
return btn;
}
// So I can identify this class in optimizeIt
private class TTButton extends JButton
{
TTButton(String theName)
{
super(theName);
}
// So I can identify this instance in OptimizeIt
public String toString() { return getText() + ": " + super.toString(); }
}
private void addWeakRef(Object thing, String theName)
{
NamedWeakRef thisRef = new NamedWeakRef(thing, theName);
myHash.add(thisRef);
}
private class NamedWeakRef extends WeakReference
{
String myName;
NamedWeakRef(Object thing, String theName)
{
super(thing, myQueue);
myName = theName;
}
}
private class Poller implements Runnable
{
public void run()
{
NamedWeakRef myRef;
while(true)
{
try
{
myRef = (NamedWeakRef)myQueue.remove();
synchronized(System.out)
{
System.out.println("GC cleaned up " + myRef.myName);
myHash.remove(myRef);
}
}
catch(InterruptedException ie) { }
}
}
}
private static void setLookAndFeel()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
//
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
}
catch (Exception lfex1)
{
System.err.println("Error setting L&F");
lfex1.printStackTrace();
}
}
}
(Review ID: 107093)
======================================================================
- backported by
-
JDK-2035362 ToolTipManager still leaks in Metal L&F
- Resolved
- duplicates
-
JDK-4391875 DefaultPopupFactory retains improper reference to "invoker"
- Closed
-
JDK-4489211 JComboBox causes memory leak when popup is opened
- Closed