Skip to content

Commit e986459

Browse files
committed
8227619: Potential memory leak in javafx.scene.control.ListView
Reviewed-by: kcr, aghaisas
1 parent a74137a commit e986459

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/SelectedItemsReadOnlyObservableList.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
2727
import javafx.collections.ListChangeListener;
2828
import javafx.collections.ObservableList;
2929
import javafx.collections.ObservableListBase;
30+
import javafx.collections.WeakListChangeListener;
3031

3132
import java.lang.ref.WeakReference;
3233
import java.util.ArrayList;
@@ -46,6 +47,8 @@ public abstract class SelectedItemsReadOnlyObservableList<E> extends ObservableL
4647
itemsListChanged = true;
4748
itemsListChange = c;
4849
};
50+
private final WeakListChangeListener weakItemsListListener =
51+
new WeakListChangeListener(itemsListListener);
4952

5053
private final Supplier<Integer> modelSizeSupplier;
5154

@@ -120,11 +123,11 @@ public int size() {
120123
// Used by ListView and TableView to allow for improved handling.
121124
public void setItemsList(ObservableList<E> itemsList) {
122125
if (this.itemsList != null) {
123-
this.itemsList.removeListener(itemsListListener);
126+
this.itemsList.removeListener(weakItemsListListener);
124127
}
125128
this.itemsList = itemsList;
126129
if (itemsList != null) {
127-
itemsList.addListener(itemsListListener);
130+
itemsList.addListener(weakItemsListListener);
128131
}
129132
}
130133

modules/javafx.controls/src/test/java/test/javafx/scene/control/ListViewTest.java

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
2828
import com.sun.javafx.scene.control.VirtualScrollBar;
2929
import com.sun.javafx.scene.control.behavior.ListCellBehavior;
3030
import com.sun.javafx.tk.Toolkit;
31+
import java.lang.ref.WeakReference;
3132
import java.util.ArrayList;
3233
import java.util.Arrays;
3334
import java.util.Collections;
@@ -1975,4 +1976,28 @@ public void testEventIndicesOnSelectRange() {
19751976
assertEquals("List item at index 1 should be selected", 1, (int) sm.getSelectedIndices().get(0));
19761977
assertEquals("List item at index 2 should be selected", 2, (int) sm.getSelectedIndices().get(1));
19771978
}
1979+
1980+
@Test
1981+
public void testListViewLeak() {
1982+
ObservableList<String> items = FXCollections.observableArrayList();
1983+
WeakReference<ListView<String>> listViewRef = new WeakReference<>(new ListView<>(items));
1984+
attemptGC(listViewRef, 10);
1985+
assertNull("ListView has a leak.", listViewRef.get());
1986+
}
1987+
1988+
private void attemptGC(WeakReference<ListView<String>> weakRef, int n) {
1989+
for (int i = 0; i < n; i++) {
1990+
System.gc();
1991+
System.runFinalization();
1992+
1993+
if (weakRef.get() == null) {
1994+
break;
1995+
}
1996+
try {
1997+
Thread.sleep(50);
1998+
} catch (InterruptedException e) {
1999+
fail("InterruptedException occurred during Thread.sleep()");
2000+
}
2001+
}
2002+
}
19782003
}

0 commit comments

Comments
 (0)