|
Replies:
10
-
Last Post:
Oct 13, 2008 2:43 AM
by: Artem Ananiev
|
|
|
|
|
|
|
Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 8, 2008 9:21 AM
|
|
|
I initially posted this in the Java SE Forum, but it's probably more appropriate here. Sorry for the cross post.
http://forums.java.net/jive/thread.jspa?threadID=48471&tstart=0
This is more a question for the AWT/Swing Engineers, but I'm putting it out to the community.
Is there a reason why the finalize() method was removed from java.awt.Window? Was the finalize() causing any dead-locks?
Currently in Java SE 6, without the finalize() method, there is a memory leak when child windows are created. More specifically, a child Window is added to an ownedWindowList Vector of the parent Window, but is never removed (Child windows used to be removed in the finalize()).
I've searched the bug parade, but didn't find any bugs about this mem leak.
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 8, 2008 9:56 AM
in response to: wwwizard
|
|
|
I got a NullPointerException while posting so I posted a second time. Marking this one as answered.
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 9, 2008 12:51 AM
in response to: wwwizard
|
|
|
swing@javadesktop.org wrote: > I initially posted this in the Java SE Forum, but it's probably more appropriate here. Sorry for the cross post. > > http://forums.java.net/jive/thread.jspa?threadID=48471&tstart=0 > > This is more a question for the AWT/Swing Engineers, but I'm putting it out to the community. > > Is there a reason why the finalize() method was removed from java.awt.Window? Was the finalize() causing any dead-locks?
finalize() method is removed as an unreliable way to free resources. Instead, we use Java2D Disposer machinery which is based on ReferenceQueue notifications. See java.lang.ref.ReferenceQueue JavaDoc for details.
> Currently in Java SE 6, without the finalize() method, there is a memory leak when child windows are created. More specifically, a child Window is added to an ownedWindowList Vector of the parent Window, but is never removed (Child windows used to be removed in the finalize()).
The leak looks strange, because only WeakReferences are stored for child windows, and these references can be freed by GC at any time. Could you provide a short test which can be used to reproduce the leak?
Thanks,
Artem
> I've searched the bug parade, but didn't find any bugs about this mem leak. > [Message sent by forum member 'wwwizard' (wwwizard)] > > http://forums.java.net/jive/thread.jspa?messageID=304002
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 9, 2008 5:35 AM
in response to: Artem Ananiev
|
|
|
When the app is run, the count of WeakReferences that don't have a referent will continually increase.
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.Vector;
/**
* The following Frame App has two Windows. Clicking on the buttons toggle
* between the two windows. Each time a Window is set visible, it creates 100
* child windows. When the other window is hidden, it disposes all its child
* windows. Using reflection, the app counts the total number of WeakReferences
* in the Window.ownedWindowList Vector, displaying the total counts of child
* windows created, the total number of WeakReferences that contain null
* references, and the total number of WeakReferences that refer to a child
* Window.
*/
public class MainFrame extends Frame {
Window parentWindow1 = new ParentWindow(this, 1);
Window parentWindow2 = new ParentWindow(this, 2);
public MainFrame() {
super("Mem Leak Test1");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
dispose();
}
});
parentWindow1.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new MainFrame().setVisible(true);
}
});
}
}
class ParentWindow extends Window {
private static final int NUM_WINS = 100;
private static final int NULL_INDEX = 0;
private static final int WEAK_INDEX = 1;
private static int numChildWindowsCreated;
private Window[] childWindows;
public ParentWindow(Window owner, int num) {
super(owner);
Button button = new Button("Click");
add(new Label("Window " + num), BorderLayout.NORTH);
add(button);
button.addActionListener(new ClickAction());
pack();
}
public void setVisible(boolean b) {
super.setVisible(b);
if (b) {
createWindows();
} else {
disposeWindows();
}
}
private void createWindows() {
childWindows = new Window[NUM_WINS];
for (int i = 0; i < childWindows.length; i++) {
childWindows[i] = new Window(this);
numChildWindowsCreated++;
}
}
private void disposeWindows() {
for (int i = 0; i < childWindows.length; i++) {
childWindows[i].dispose();
childWindows[i] = null;
}
childWindows = null;
}
private class ClickAction implements ActionListener {
public void actionPerformed(ActionEvent evt) {
MainFrame owner = (MainFrame) getOwner();
Window other = (ParentWindow.this == owner.parentWindow1)
? owner.parentWindow2 : owner.parentWindow1;
setVisible(false);
other.setVisible(true);
int[] counts = new int[2];
countOwnedWindows(owner.parentWindow1, counts);
countOwnedWindows(owner.parentWindow2, counts);
System.out.println("*********************************");
System.out.println("Win Count: " + numChildWindowsCreated);
System.out.println("Null Count: " + counts[NULL_INDEX]);
System.out.println("Weak Count: " + counts[WEAK_INDEX]);
}
private void countOwnedWindows(Window window, int[] counts) {
try {
Field field = Window.class.getDeclaredField("ownedWindowList");
field.setAccessible(true);
Vector vector = (Vector) field.get(window);
Enumeration e = vector.elements();
while (e.hasMoreElements()) {
WeakReference ref = (WeakReference) e.nextElement();
if (ref.get() == null) {
counts[NULL_INDEX]++;
} else {
counts[WEAK_INDEX]++;
}
}
//IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException
} catch (Exception ex) {
ex.printStackTrace();
System.exit(0);
}
}
}
}
Sample output:
*********************************
Win Count: 200
Null Count: 0
Weak Count: 200
*********************************
Win Count: 300
Null Count: 0
Weak Count: 300
*********************************
Win Count: 400
Null Count: 0
Weak Count: 400
*********************************
Win Count: 500
Null Count: 0
Weak Count: 500
*********************************
Win Count: 600
Null Count: 0
Weak Count: 600
*********************************
Win Count: 700
Null Count: 0
Weak Count: 700
*********************************
Win Count: 800
Null Count: 579
Weak Count: 221
*********************************
Win Count: 900
Null Count: 579
Weak Count: 321
*********************************
Win Count: 1000
Null Count: 579
Weak Count: 421
*********************************
Win Count: 1100
Null Count: 579
Weak Count: 521
*********************************
Win Count: 1200
Null Count: 579
Weak Count: 621
*********************************
Win Count: 1300
Null Count: 579
Weak Count: 721
*********************************
Win Count: 1400
Null Count: 1176
Weak Count: 224
*********************************
Win Count: 1500
Null Count: 1176
Weak Count: 324
*********************************
Win Count: 1600
Null Count: 1176
Weak Count: 424
*********************************
Win Count: 1700
Null Count: 1176
Weak Count: 524
*********************************
Win Count: 1800
Null Count: 1176
Weak Count: 624
*********************************
Win Count: 1900
Null Count: 1176
Weak Count: 724
*********************************
Win Count: 2000
Null Count: 1756
Weak Count: 244
*********************************
Win Count: 2100
Null Count: 1756
Weak Count: 344
*********************************
Win Count: 2200
Null Count: 1756
Weak Count: 444
*********************************
Win Count: 2300
Null Count: 1756
Weak Count: 544
*********************************
Win Count: 2400
Null Count: 1756
Weak Count: 644
*********************************
Win Count: 2500
Null Count: 1756
Weak Count: 744
*********************************
Win Count: 2600
Null Count: 2292
Weak Count: 308
*********************************
Win Count: 2700
Null Count: 2292
Weak Count: 408
*********************************
Win Count: 2800
Null Count: 2292
Weak Count: 508
*********************************
Win Count: 2900
Null Count: 2292
Weak Count: 608
*********************************
Win Count: 3000
Null Count: 2292
Weak Count: 708
*********************************
Win Count: 3100
Null Count: 2792
Weak Count: 308
*********************************
Win Count: 3200
Null Count: 2792
Weak Count: 408
*********************************
Win Count: 3300
Null Count: 2792
Weak Count: 508
*********************************
Win Count: 3400
Null Count: 2792
Weak Count: 608
*********************************
Win Count: 3500
Null Count: 2792
Weak Count: 708
*********************************
Win Count: 3600
Null Count: 2792
Weak Count: 808
*********************************
Win Count: 3700
Null Count: 2997
Weak Count: 703
*********************************
Win Count: 3800
Null Count: 2997
Weak Count: 803
*********************************
Win Count: 3900
Null Count: 2997
Weak Count: 903
*********************************
Win Count: 4000
Null Count: 2997
Weak Count: 1003
*********************************
Win Count: 4100
Null Count: 2997
Weak Count: 1103
*********************************
Win Count: 4200
Null Count: 2997
Weak Count: 1203
*********************************
Win Count: 4300
Null Count: 3509
Weak Count: 791
*********************************
Win Count: 4400
Null Count: 3509
Weak Count: 891
*********************************
Win Count: 4500
Null Count: 3509
Weak Count: 991
*********************************
Win Count: 4600
Null Count: 3509
Weak Count: 1091
*********************************
Win Count: 4700
Null Count: 3509
Weak Count: 1191
*********************************
Win Count: 4800
Null Count: 4009
Weak Count: 791
*********************************
Win Count: 4900
Null Count: 4009
Weak Count: 891
*********************************
Win Count: 5000
Null Count: 4009
Weak Count: 991
*********************************
Win Count: 5100
Null Count: 4009
Weak Count: 1091
*********************************
Win Count: 5200
Null Count: 4009
Weak Count: 1191
*********************************
Win Count: 5300
Null Count: 4009
Weak Count: 1291
*********************************
Win Count: 5400
Null Count: 4371
Weak Count: 1029
*********************************
Win Count: 5500
Null Count: 4371
Weak Count: 1129
*********************************
Win Count: 5600
Null Count: 4371
Weak Count: 1229
*********************************
Win Count: 5700
Null Count: 4371
Weak Count: 1329
*********************************
Win Count: 5800
Null Count: 4371
Weak Count: 1429
*********************************
Win Count: 5900
Null Count: 4871
Weak Count: 1029
*********************************
Win Count: 6000
Null Count: 4871
Weak Count: 1129
*********************************
Win Count: 6100
Null Count: 4871
Weak Count: 1229
*********************************
Win Count: 6200
Null Count: 4871
Weak Count: 1329
*********************************
Win Count: 6300
Null Count: 4871
Weak Count: 1429
*********************************
Win Count: 6400
Null Count: 4871
Weak Count: 1529
*********************************
Win Count: 6500
Null Count: 5362
Weak Count: 1138
*********************************
Win Count: 6600
Null Count: 5362
Weak Count: 1238
*********************************
Win Count: 6700
Null Count: 5362
Weak Count: 1338
*********************************
Win Count: 6800
Null Count: 5362
Weak Count: 1438
*********************************
Win Count: 6900
Null Count: 5362
Weak Count: 1538
*********************************
Win Count: 7000
Null Count: 5855
Weak Count: 1145
*********************************
Win Count: 7100
Null Count: 5855
Weak Count: 1245
*********************************
Win Count: 7200
Null Count: 5855
Weak Count: 1345
*********************************
Win Count: 7300
Null Count: 5855
Weak Count: 1445
*********************************
Win Count: 7400
Null Count: 5855
Weak Count: 1545
*********************************
Win Count: 7500
Null Count: 6355
Weak Count: 1145
*********************************
Win Count: 7600
Null Count: 6355
Weak Count: 1245
*********************************
Win Count: 7700
Null Count: 6355
Weak Count: 1345
*********************************
Win Count: 7800
Null Count: 6355
Weak Count: 1445
*********************************
Win Count: 7900
Null Count: 6355
Weak Count: 1545
*********************************
Win Count: 8000
Null Count: 6355
Weak Count: 1645
*********************************
Win Count: 8100
Null Count: 6816
Weak Count: 1284
*********************************
Win Count: 8200
Null Count: 6816
Weak Count: 1384
*********************************
Win Count: 8300
Null Count: 6816
Weak Count: 1484
*********************************
Win Count: 8400
Null Count: 6816
Weak Count: 1584
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 9, 2008 5:44 AM
in response to: wwwizard
|
|
|
swing@javadesktop.org wrote: > When the app is run, the count of WeakReferences that don't have a referent will continually increase.
This doesn't mean a leak. Try the following simple scenario:
1. Create an instance of class which is suspected to leak (child window) 2. Make a weak reference to this instance, and remove all the strong references 3. Consume all the available heap (for example, by allocating byte arrays in a loop and storing them in a Vector) 4. Check the value of your weak reference. If it is not null, then some other code (AWT) holds a strong reference to the same object.
Thanks,
Artem
> > import java.awt.BorderLayout;
> import java.awt.Button;
> import java.awt.EventQueue;
> import java.awt.Frame;
> import java.awt.Label;
> import java.awt.Window;
> import java.awt.event.ActionEvent;
> import java.awt.event.ActionListener;
> import java.awt.event.WindowAdapter;
> import java.awt.event.WindowEvent;
> import java.lang.ref.WeakReference;
> import java.lang.reflect.Field;
> import java.util.Enumeration;
> import java.util.Vector;
>
> /**
> * The following Frame App has two Windows. Clicking on the buttons toggle
> * between the two windows. Each time a Window is set visible, it creates 100
> * child windows. When the other window is hidden, it disposes all its child
> * windows. Using reflection, the app counts the total number of WeakReferences
> * in the Window.ownedWindowList Vector, displaying the total counts of child
> * windows created, the total number of WeakReferences that contain null
> * references, and the total number of WeakReferences that refer to a child
> * Window.
> */
> public class MainFrame extends Frame {
>
> Window parentWindow1 = new ParentWindow(this, 1);
> Window parentWindow2 = new ParentWindow(this, 2);
>
> public MainFrame() {
> super("Mem Leak Test1");
>
> addWindowListener(new WindowAdapter() {
> public void windowClosing(WindowEvent evt) {
> dispose();
> }
> });
>
> parentWindow1.setVisible(true);
> }
>
> public static void main(String[] args) {
> EventQueue.invokeLater(new Runnable() {
> public void run() {
> new MainFrame().setVisible(true);
> }
> });
> }
> }
>
> class ParentWindow extends Window {
>
> private static final int NUM_WINS = 100;
> private static final int NULL_INDEX = 0;
> private static final int WEAK_INDEX = 1;
>
> private static int numChildWindowsCreated;
>
> private Window[] childWindows;
>
> public ParentWindow(Window owner, int num) {
> super(owner);
>
> Button button = new Button("Click");
>
> add(new Label("Window " + num), BorderLayout.NORTH);
> add(button);
>
> button.addActionListener(new ClickAction());
>
> pack();
> }
>
> public void setVisible(boolean b) {
> super.setVisible(b);
>
> if (b) {
> createWindows();
> } else {
> disposeWindows();
> }
> }
>
> private void createWindows() {
> childWindows = new Window[NUM_WINS];
>
> for (int i = 0; i < childWindows.length; i++) {
> childWindows[i] = new Window(this);
> numChildWindowsCreated++;
> }
> }
>
> private void disposeWindows() {
> for (int i = 0; i < childWindows.length; i++) {
> childWindows[i].dispose();
> childWindows[i] = null;
> }
>
> childWindows = null;
> }
>
> private class ClickAction implements ActionListener {
>
> public void actionPerformed(ActionEvent evt) {
> MainFrame owner = (MainFrame) getOwner();
>
> Window other = (ParentWindow.this == owner.parentWindow1)
> ? owner.parentWindow2 : owner.parentWindow1;
>
> setVisible(false);
> other.setVisible(true);
>
> int[] counts = new int[2];
>
> countOwnedWindows(owner.parentWindow1, counts);
> countOwnedWindows(owner.parentWindow2, counts);
>
> System.out.println("*********************************");
> System.out.println("Win Count: " + numChildWindowsCreated);
> System.out.println("Null Count: " + counts[NULL_INDEX]);
> System.out.println("Weak Count: " + counts[WEAK_INDEX]);
> }
>
> private void countOwnedWindows(Window window, int[] counts) {
> try {
> Field field = Window.class.getDeclaredField("ownedWindowList");
> field.setAccessible(true);
>
> Vector vector = (Vector) field.get(window);
>
> Enumeration e = vector.elements();
>
> while (e.hasMoreElements()) {
> WeakReference ref = (WeakReference) e.nextElement();
>
> if (ref.get() == null) {
> counts[NULL_INDEX]++;
> } else {
> counts[WEAK_INDEX]++;
> }
> }
> //IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException
> } catch (Exception ex) {
> ex.printStackTrace();
> System.exit(0);
> }
> }
> }
> }
>
> Sample output: > > *********************************
> Win Count: 200
> Null Count: 0
> Weak Count: 200
> *********************************
> Win Count: 300
> Null Count: 0
> Weak Count: 300
> *********************************
> Win Count: 400
> Null Count: 0
> Weak Count: 400
> *********************************
> Win Count: 500
> Null Count: 0
> Weak Count: 500
> *********************************
> Win Count: 600
> Null Count: 0
> Weak Count: 600
> *********************************
> Win Count: 700
> Null Count: 0
> Weak Count: 700
> *********************************
> Win Count: 800
> Null Count: 579
> Weak Count: 221
> *********************************
> Win Count: 900
> Null Count: 579
> Weak Count: 321
> *********************************
> Win Count: 1000
> Null Count: 579
> Weak Count: 421
> *********************************
> Win Count: 1100
> Null Count: 579
> Weak Count: 521
> *********************************
> Win Count: 1200
> Null Count: 579
> Weak Count: 621
> *********************************
> Win Count: 1300
> Null Count: 579
> Weak Count: 721
> *********************************
> Win Count: 1400
> Null Count: 1176
> Weak Count: 224
> *********************************
> Win Count: 1500
> Null Count: 1176
> Weak Count: 324
> *********************************
> Win Count: 1600
> Null Count: 1176
> Weak Count: 424
> *********************************
> Win Count: 1700
> Null Count: 1176
> Weak Count: 524
> *********************************
> Win Count: 1800
> Null Count: 1176
> Weak Count: 624
> *********************************
> Win Count: 1900
> Null Count: 1176
> Weak Count: 724
> *********************************
> Win Count: 2000
> Null Count: 1756
> Weak Count: 244
> *********************************
> Win Count: 2100
> Null Count: 1756
> Weak Count: 344
> *********************************
> Win Count: 2200
> Null Count: 1756
> Weak Count: 444
> *********************************
> Win Count: 2300
> Null Count: 1756
> Weak Count: 544
> *********************************
> Win Count: 2400
> Null Count: 1756
> Weak Count: 644
> *********************************
> Win Count: 2500
> Null Count: 1756
> Weak Count: 744
> *********************************
> Win Count: 2600
> Null Count: 2292
> Weak Count: 308
> *********************************
> Win Count: 2700
> Null Count: 2292
> Weak Count: 408
> *********************************
> Win Count: 2800
> Null Count: 2292
> Weak Count: 508
> *********************************
> Win Count: 2900
> Null Count: 2292
> Weak Count: 608
> *********************************
> Win Count: 3000
> Null Count: 2292
> Weak Count: 708
> *********************************
> Win Count: 3100
> Null Count: 2792
> Weak Count: 308
> *********************************
> Win Count: 3200
> Null Count: 2792
> Weak Count: 408
> *********************************
> Win Count: 3300
> Null Count: 2792
> Weak Count: 508
> *********************************
> Win Count: 3400
> Null Count: 2792
> Weak Count: 608
> *********************************
> Win Count: 3500
> Null Count: 2792
> Weak Count: 708
> *********************************
> Win Count: 3600
> Null Count: 2792
> Weak Count: 808
> *********************************
> Win Count: 3700
> Null Count: 2997
> Weak Count: 703
> *********************************
> Win Count: 3800
> Null Count: 2997
> Weak Count: 803
> *********************************
> Win Count: 3900
> Null Count: 2997
> Weak Count: 903
> *********************************
> Win Count: 4000
> Null Count: 2997
> Weak Count: 1003
> *********************************
> Win Count: 4100
> Null Count: 2997
> Weak Count: 1103
> *********************************
> Win Count: 4200
> Null Count: 2997
> Weak Count: 1203
> *********************************
> Win Count: 4300
> Null Count: 3509
> Weak Count: 791
> *********************************
> Win Count: 4400
> Null Count: 3509
> Weak Count: 891
> *********************************
> Win Count: 4500
> Null Count: 3509
> Weak Count: 991
> *********************************
> Win Count: 4600
> Null Count: 3509
> Weak Count: 1091
> *********************************
> Win Count: 4700
> Null Count: 3509
> Weak Count: 1191
> *********************************
> Win Count: 4800
> Null Count: 4009
> Weak Count: 791
> *********************************
> Win Count: 4900
> Null Count: 4009
> Weak Count: 891
> *********************************
> Win Count: 5000
> Null Count: 4009
> Weak Count: 991
> *********************************
> Win Count: 5100
> Null Count: 4009
> Weak Count: 1091
> *********************************
> Win Count: 5200
> Null Count: 4009
> Weak Count: 1191
> *********************************
> Win Count: 5300
> Null Count: 4009
> Weak Count: 1291
> *********************************
> Win Count: 5400
> Null Count: 4371
> Weak Count: 1029
> *********************************
> Win Count: 5500
> Null Count: 4371
> Weak Count: 1129
> *********************************
> Win Count: 5600
> Null Count: 4371
> Weak Count: 1229
> *********************************
> Win Count: 5700
> Null Count: 4371
> Weak Count: 1329
> *********************************
> Win Count: 5800
> Null Count: 4371
> Weak Count: 1429
> *********************************
> Win Count: 5900
> Null Count: 4871
> Weak Count: 1029
> *********************************
> Win Count: 6000
> Null Count: 4871
> Weak Count: 1129
> *********************************
> Win Count: 6100
> Null Count: 4871
> Weak Count: 1229
> *********************************
> Win Count: 6200
> Null Count: 4871
> Weak Count: 1329
> *********************************
> Win Count: 6300
> Null Count: 4871
> Weak Count: 1429
> *********************************
> Win Count: 6400
> Null Count: 4871
> Weak Count: 1529
> *********************************
> Win Count: 6500
> Null Count: 5362
> Weak Count: 1138
> *********************************
> Win Count: 6600
> Null Count: 5362
> Weak Count: 1238
> *********************************
> Win Count: 6700
> Null Count: 5362
> Weak Count: 1338
> *********************************
> Win Count: 6800
> Null Count: 5362
> Weak Count: 1438
> *********************************
> Win Count: 6900
> Null Count: 5362
> Weak Count: 1538
> *********************************
> Win Count: 7000
> Null Count: 5855
> Weak Count: 1145
> *********************************
> Win Count: 7100
> Null Count: 5855
> Weak Count: 1245
> *********************************
> Win Count: 7200
> Null Count: 5855
> Weak Count: 1345
> *********************************
> Win Count: 7300
> Null Count: 5855
> Weak Count: 1445
> *********************************
> Win Count: 7400
> Null Count: 5855
> Weak Count: 1545
> *********************************
> Win Count: 7500
> Null Count: 6355
> Weak Count: 1145
> *********************************
> Win Count: 7600
> Null Count: 6355
> Weak Count: 1245
> *********************************
> Win Count: 7700
> Null Count: 6355
> Weak Count: 1345
> *********************************
> Win Count: 7800
> Null Count: 6355
> Weak Count: 1445
> *********************************
> Win Count: 7900
> Null Count: 6355
> Weak Count: 1545
> *********************************
> Win Count: 8000
> Null Count: 6355
> Weak Count: 1645
> *********************************
> Win Count: 8100
> Null Count: 6816
> Weak Count: 1284
> *********************************
> Win Count: 8200
> Null Count: 6816
> Weak Count: 1384
> *********************************
> Win Count: 8300
> Null Count: 6816
> Weak Count: 1484
> *********************************
> Win Count: 8400
> Null Count: 6816
> Weak Count: 1584
>
> [Message sent by forum member 'wwwizard' (wwwizard)] > > http://forums.java.net/jive/thread.jspa?messageID=304278
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 9, 2008 5:44 AM
in response to: Artem Ananiev
|
|
|
> The leak looks strange, because only WeakReferences > are stored for child > windows, and these references can be freed by GC at > any time. Could you > provide a short test which can be used to reproduce > the leak?
The child windows are GCed, but the Window.ownedWindowList Vector keeps the references to the WeakReferences which are not GCed.
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 9, 2008 5:49 AM
in response to: wwwizard
|
|
|
swing@javadesktop.org wrote: >> The leak looks strange, because only WeakReferences >> are stored for child >> windows, and these references can be freed by GC at >> any time. Could you >> provide a short test which can be used to reproduce >> the leak? > > The child windows are GCed, but the Window.ownedWindowList Vector keeps the references to the WeakReferences which are not GCed.
This looks odd, because weak reference is removed from parent's list when the corresponding window is collected...
Thanks,
Artem
> [Message sent by forum member 'wwwizard' (wwwizard)] > > http://forums.java.net/jive/thread.jspa?messageID=304281
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 9, 2008 9:46 AM
in response to: Artem Ananiev
|
|
|
I ran the above code in the NetBeans debugger. I just started the app and checked the number of instances of WindowDisposerRecord. I had 103 instances:
1 MainFrame 2 ParentWindows 100 child Windows
All of the WindowDisposerRecord.owners return null.
static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
final WeakReference<Window> owner;
final WeakReference weakThis;
final AppContext context;
WindowDisposerRecord(AppContext context, Window victim) {
owner = new WeakReference<Window>(victim.getOwner());
weakThis = victim.weakThis;
this.context = context;
}
public void dispose() {
Window parent = owner.get(); //always returns null
if (parent != null) { //so it will never enter if
parent.removeOwnedWindow(weakThis); //WeakRef never removed from OwnedWindowList
}
Window.removeFromWindowList(context, weakThis);
}
}
In dispose(), the parent is always null, so it never enters the if block, so it doesn't remove the WeakReference from the ownedWindowList.
In this example, the Disposer doesn't seem to be able to properly dispose WeakReferences to Windows.
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 10, 2008 10:31 PM
in response to: wwwizard
|
|
|
If parent returned from get is null it means that it has already been collected, which means that there's nothing to remove the reference from.
Dmitri
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 12, 2008 6:01 PM
in response to: trembovetski
|
|
|
In the sample code above, the MainFrame has strong references to the two parent Windows, so these two windows are never GCed. Yet when the child windows are disposed with the WindowDisposerRecord, the WeakReferences to the parents are null, even tho the parents are still strongly referenced.So the child windows are never removed from the two parent windows.
We automated our app to run for three days. There was over 200000 WeakReferences. The huge majority of these WeakReferences are held by the ownedWindowList Vector in Window.
|
|
|
|
|
|
|
|
Re: Removed finalize() in java.awt.Window in Java SE 6
Posted:
Oct 13, 2008 2:43 AM
in response to: wwwizard
|
|
|
swing@javadesktop.org wrote: > I ran the above code in the NetBeans debugger. I just started the app and checked the number of instances of WindowDisposerRecord. I had 103 instances: > > 1 MainFrame > 2 ParentWindows > 100 child Windows > > All of the WindowDisposerRecord.owners return null.
OK, I see... I have just filed a bug 6758673 against AWT, it will be visible via bugs.sun.com in a few hours or so.
The root cause of the problem is that WindowDisposerRecord is created too early - in init(gc) - when victim's owner hasn't been initialized yet. To fix the bug we just need to move WDR creation from init() to ownedInit().
Thanks,
Artem
> > static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
> final WeakReference<Window> owner;
> final WeakReference weakThis;
> final AppContext context;
> WindowDisposerRecord(AppContext context, Window victim) {
> owner = new WeakReference<Window>(victim.getOwner());
> weakThis = victim.weakThis;
> this.context = context;
> }
> public void dispose() {
> Window parent = owner.get(); //always returns null
> if (parent != null) { //so it will never enter if
> parent.removeOwnedWindow(weakThis); //WeakRef never removed from OwnedWindowList
> }
> Window.removeFromWindowList(context, weakThis);
> }
> }
>
> > In dispose(), the parent is always null, so it never enters the if block, so it doesn't remove the WeakReference from the ownedWindowList. > > In this example, the Disposer doesn't seem to be able to properly dispose WeakReferences to Windows. > [Message sent by forum member 'wwwizard' (wwwizard)] > > http://forums.java.net/jive/thread.jspa?messageID=304356
|
|
|
|
|