-
Bug
-
Resolution: Fixed
-
P2
-
1.0.1, 1.2.0
-
None
-
1.0.2
-
generic, sparc
-
solaris_2.5.1, solaris_2.6
Date: Tue, 24 Mar 1998 16:41:14 +1000
From: "Kent Fitch" <###@###.###>
Subject: Swing 1 Tooltips causing memory leak with "HEAVY" popup
To: Richard.Schiavi@Eng
Cc: ###@###.###
Hi there,
I guess you are all at JavaOne. This is one for when you get
back to work. I've been tracing memory problems in our applic-
ation and the latest I have confirmed is due to the behaviour
of tooltips. Here is what happens:
Our application JFrame contains several panels. A user action
in one panel can cause another panel to be removed from the
JFrame's hierarchy and replaced with another, new panel.
If the panel which is removed *ever* contained a tooltip, then
that panel is not garbage collected, and hence any objects which
it points to cannot be garbage collected.
This is what I think happens:
The ToolTipManager in our case chooses to display tooltips
in a "HEAVY" window: the WindowPopup inner class. Showing
this window adds it to the JFrame's "ownedWindows" vector.
This tolltip window is hide()'en, but not disposed(). I think a
dispose() results in it being removed from the ownedWindows
vector, but this never happens.
The tooltip WindowPopup points to a JToolTip and it's component
field points to the panel it was popped up from.
Hence, the JFrame maintains a ref to the WindowPopup which
maintains a ref to the panel, which points to our large and
now uncollectable objects.
I made this source change to ToolTipManager which fixed the
problem for us (but I dunno what the side effects are...):
To the inner class:
class WindowPopup extends Window implements Popup {
I added this instance field:
boolean beingDisposed = false ; // added kkf at csiro
I changed WindowPopup's hide() method like this:
public void hide() {
if (beingDisposed) return ;// kkf at csiro
else beingDisposed = true ;// kkf at csiro
super.hide();
dispose() ; // kkf at csiro
/** We need to call removeNotify() here because hide() does
something only if
* Component.visible is true. When the app frame is miniaturized,
the parent
* frame of this frame is invisible, causing AWT to believe that
this frame
* is invisible and causing hide() to do nothing
*/
removeNotify();
}
(That stuff about removeNotify was already there).
I found this by running it under Netscape 4.04, doing a complete
memory dump ("X") and processing this file with HeapWalk:
http://www.csiro.au/itsb/kent/HeapWalk.html
I navigated to the object I didnt know why was in memory, and
right-mouse clicked to print a trail of references to this
object (there were 7386....). I navigated back from all the
"root" objects to find a path to the object which was
mysteriously in memory. All the root paths went thru the
JFrame, via its ownedWindows vector to the WindowPopUp, the
layout manager, the JToolTip and hence to the removed panel.
Im not sure what to do. Disabling tooltips also prevents
the memory leak, but our users like them. I am very uneasy
about running a "patched" copy of the ToolTipManager, as we
are then relying on nonstandard behaviour.
I am hoping I have missed something, or that there is a better
way to fix this problem.
Regards,
Kent Fitch Ph: +61 2 6276 6711
ITS CSIRO Canberra Australia ###@###.###
"Unusual travel arrangements are dancing lessons from the gods."
- Kurt Vonnegut
From: "Kent Fitch" <###@###.###>
Subject: Swing 1 Tooltips causing memory leak with "HEAVY" popup
To: Richard.Schiavi@Eng
Cc: ###@###.###
Hi there,
I guess you are all at JavaOne. This is one for when you get
back to work. I've been tracing memory problems in our applic-
ation and the latest I have confirmed is due to the behaviour
of tooltips. Here is what happens:
Our application JFrame contains several panels. A user action
in one panel can cause another panel to be removed from the
JFrame's hierarchy and replaced with another, new panel.
If the panel which is removed *ever* contained a tooltip, then
that panel is not garbage collected, and hence any objects which
it points to cannot be garbage collected.
This is what I think happens:
The ToolTipManager in our case chooses to display tooltips
in a "HEAVY" window: the WindowPopup inner class. Showing
this window adds it to the JFrame's "ownedWindows" vector.
This tolltip window is hide()'en, but not disposed(). I think a
dispose() results in it being removed from the ownedWindows
vector, but this never happens.
The tooltip WindowPopup points to a JToolTip and it's component
field points to the panel it was popped up from.
Hence, the JFrame maintains a ref to the WindowPopup which
maintains a ref to the panel, which points to our large and
now uncollectable objects.
I made this source change to ToolTipManager which fixed the
problem for us (but I dunno what the side effects are...):
To the inner class:
class WindowPopup extends Window implements Popup {
I added this instance field:
boolean beingDisposed = false ; // added kkf at csiro
I changed WindowPopup's hide() method like this:
public void hide() {
if (beingDisposed) return ;// kkf at csiro
else beingDisposed = true ;// kkf at csiro
super.hide();
dispose() ; // kkf at csiro
/** We need to call removeNotify() here because hide() does
something only if
* Component.visible is true. When the app frame is miniaturized,
the parent
* frame of this frame is invisible, causing AWT to believe that
this frame
* is invisible and causing hide() to do nothing
*/
removeNotify();
}
(That stuff about removeNotify was already there).
I found this by running it under Netscape 4.04, doing a complete
memory dump ("X") and processing this file with HeapWalk:
http://www.csiro.au/itsb/kent/HeapWalk.html
I navigated to the object I didnt know why was in memory, and
right-mouse clicked to print a trail of references to this
object (there were 7386....). I navigated back from all the
"root" objects to find a path to the object which was
mysteriously in memory. All the root paths went thru the
JFrame, via its ownedWindows vector to the WindowPopUp, the
layout manager, the JToolTip and hence to the removed panel.
Im not sure what to do. Disabling tooltips also prevents
the memory leak, but our users like them. I am very uneasy
about running a "patched" copy of the ToolTipManager, as we
are then relying on nonstandard behaviour.
I am hoping I have missed something, or that there is a better
way to fix this problem.
Regards,
Kent Fitch Ph: +61 2 6276 6711
ITS CSIRO Canberra Australia ###@###.###
"Unusual travel arrangements are dancing lessons from the gods."
- Kurt Vonnegut