<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
Since there is already a bug tracking this, can you add the
additional information and test case to the bug report?<br>
<br>
-- Kevin<br>
<br>
<br>
<div class="moz-cite-prefix">On 12/4/2025 11:44 AM, Andy Goryachev
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CY8PR10MB72656E806C8CC9D1108BAA56E5A6A@CY8PR10MB7265.namprd10.prod.outlook.com">
<div dir="ltr" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Spoke too soon: we already have </div>
<div dir="ltr" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<a href="https://bugs.openjdk.org/browse/JDK-8184166" data-outlook-id="374b16ff-53cf-48f4-9416-33de9096ced2" moz-do-not-send="true" class="moz-txt-link-freetext">https://bugs.openjdk.org/browse/JDK-8184166</a></div>
<div dir="ltr" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
from 2017.</div>
<div dir="ltr" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div dir="ltr" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Question: are there any more places where we don't null the
unused entries?</div>
<div dir="ltr" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div dir="ltr" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
-andy</div>
<div dir="ltr" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="mail-editor-reference-message-container">
<div class="ms-outlook-mobile-reference-message skipProofing" style="text-align: left; padding: 3pt 0in 0in; border-width: 1pt medium medium; border-style: solid none none; border-color: rgb(181, 196, 223) currentcolor currentcolor; font-family: Aptos; font-size: 12pt; color: black;">
<b>From: </b>openjfx-dev <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev-retn@openjdk.org"><openjfx-dev-retn@openjdk.org></a>
on behalf of Andy Goryachev <a class="moz-txt-link-rfc2396E" href="mailto:andy.goryachev@oracle.com"><andy.goryachev@oracle.com></a><br>
<b>Date: </b>Thursday, December 4, 2025 at 11:40<br>
<b>To: </b>John Hendrikx <a class="moz-txt-link-rfc2396E" href="mailto:john.hendrikx@gmail.com"><john.hendrikx@gmail.com></a>,
<a class="moz-txt-link-abbreviated" href="mailto:openjfx-dev@openjdk.org">openjfx-dev@openjdk.org</a> <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org"><openjfx-dev@openjdk.org></a><br>
<b>Subject: </b>Re: SortedList hanging on to references &
preventing GC<br>
<br>
</div>
<div dir="ltr" class="ms-outlook-mobile-reference-message skipProofing"><span style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">>
</span><span style="font-family: Aptos; font-size: 16px; color: rgb(33, 33, 33);">Time
pressure and insufficient testing.</span></div>
<div dir="ltr" class="ms-outlook-mobile-reference-message skipProofing" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div dir="ltr" class="ms-outlook-mobile-reference-message skipProofing" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Alas! I can create a ticket, unless someone has already
created one.</div>
<div dir="ltr" class="ms-outlook-mobile-reference-message skipProofing" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div dir="ltr" class="ms-outlook-mobile-reference-message skipProofing" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
-andy</div>
<div dir="ltr" class="ms-outlook-mobile-reference-message skipProofing" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div dir="ltr" class="ms-outlook-mobile-reference-message skipProofing" style="font-family: "Iosevka Fixed SS16", Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="mail-editor-reference-message-container">
<div class="ms-outlook-mobile-reference-message skipProofing" style="text-align: left; padding: 3pt 0in 0in; border-width: 1pt medium medium; border-style: solid none none; border-color: rgb(181, 196, 223) currentcolor currentcolor; font-family: Aptos; font-size: 12pt; color: black;">
<b>From: </b>openjfx-dev
<a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev-retn@openjdk.org"><openjfx-dev-retn@openjdk.org></a> on behalf of John
Hendrikx <a class="moz-txt-link-rfc2396E" href="mailto:john.hendrikx@gmail.com"><john.hendrikx@gmail.com></a><br>
<b>Date: </b>Thursday, December 4, 2025 at 11:18<br>
<b>To: </b><a class="moz-txt-link-abbreviated" href="mailto:openjfx-dev@openjdk.org">openjfx-dev@openjdk.org</a>
<a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org"><openjfx-dev@openjdk.org></a><br>
<b>Subject: </b>Re: SortedList hanging on to references
& preventing GC<br>
<br>
</div>
<p class="ms-outlook-mobile-reference-message skipProofing">This
looks like a classic problem where unused elements in an
array are not nulled. Looking at the code that updates the
`size` field, there are a few code paths that are not
setting unused elements to null. I also saw no code that
ever shrinks the arrays. So it looks this implementation is
only half finished.</p>
<p class="ms-outlook-mobile-reference-message skipProofing">So,
yes, I'd say this is a bug.</p>
<blockquote>
<div class="ms-outlook-mobile-reference-message skipProofing">I'm
going to guess there's a very good reason for this
behaviour.</div>
</blockquote>
<div class="ms-outlook-mobile-reference-message skipProofing">Time
pressure and insufficient testing.</div>
<p class="ms-outlook-mobile-reference-message skipProofing">--John</p>
<div class="moz-cite-prefix">On 04/12/2025 19:40, Cormac
Redmond wrote:</div>
<blockquote>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;">Hi,</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;">I've traced a
memory issue back to a SortedList (surprisingly), where
it's hanging on to objects that could/should have been
GC'd.</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;">SortedList's
internal arrays will only grow (but not shrink) in line
with the source ObservableList (I'm sure there are reasons
for this). So even when your source ObservableList
shrinks, SortedList is hanging on to references to objects
the source list once contained, even though they're
completely removed from the source list.</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;">This leads to a
substantial waste of memory, especially when just one
momentarily large dataset leads to a permanent spike in
unnecessary memory usage for the remainder for the
application's lifetime. I'm sure I'm not the first to
raise this or ask about it & I'm going to guess
there's a very good reason for this behaviour. But could
someone explain this? I would have thought SortedList
should/could remain as lean as the source list.
FilteredList is somewhat similar, except it stores an
array of ints (indexes), so less of a memory hit, but
still pointless nonetheless.</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;">Example GIF +
code below: setup a typical sortable table (so,
ObservableList + FilteredList + SortableList), where the
print button shows that when you add a lot of data, and
remove it, SortedList retains references to all of the old
objects. Some reflection is used to print that
information.</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><img src="cid:part1.e6Gh6W2s.Q9xvDltu@oracle.com" alt="sorted_list_mem.gif" width="406" height="562" style="width: 406px; height: 562px;" class=""></div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;">Code to
reproduce:</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: monospace;">public class
SortedListMemWasteDemo extends Application {<br>
<br>
record PotentialLargeData(String info) {}<br>
<br>
public static void main(String[] args) {<br>
launch(args);<br>
}<br>
<br>
@Override<br>
public void start(Stage primaryStage) {<br>
ObservableList<PotentialLargeData>
masterData = FXCollections.observableArrayList(<br>
new PotentialLargeData("Initial info 1"),<br>
new PotentialLargeData("Initial info 2"));<br>
<br>
TableColumn<PotentialLargeData, String> col
= new TableColumn<>("Info");<br>
col.setCellValueFactory(cellData -> new
SimpleStringProperty(cellData.getValue().info()));<br>
<br>
TableView<PotentialLargeData> table = new
TableView<>();<br>
table.getColumns().add(col);<br>
<br>
FilteredList<PotentialLargeData>
filteredData = new FilteredList<>(masterData, item
-> true);<br>
SortedList<PotentialLargeData> sortedData =
new SortedList<>(filteredData);<br>
sortedData.comparatorProperty().bind(table.comparatorProperty());<br>
table.setItems(sortedData);<br>
<br>
Button loadManyBtn = new Button("Add 10,000
items");<br>
loadManyBtn.setOnAction(e -> {<br>
System.out.println("Adding 10000 items to
master data");<br>
masterData.clear();<br>
for (int i = 0; i < 10000; i++)
masterData.add(new PotentialLargeData("Info item " + i));<br>
});<br>
<br>
Button reduceBtn = new Button("Reduce to 2");<br>
reduceBtn.setOnAction(e -> {<br>
System.out.println("Reducing master data size
to 2");<br>
masterData.setAll(new PotentialLargeData("New
info 1"), new PotentialLargeData("New info 2"));<br>
});<br>
<br>
Button printBtn = new Button("Print interal
sizes");<br>
printBtn.setOnAction(e -> {<br>
try {<br>
System.out.println("Items the user sees: "
+ sortedData.size());<br>
int[] filtered = (int[])
getFieldValue(filteredData, "filtered");<br>
System.out.println("FilteredList.filtered
length: " + filtered.length);<br>
// This is a hidden and significant waste
of memory<br>
Object[] sorted = (Object[])
getFieldValue(sortedData, "sorted");<br>
System.out.println("SortedList.sorted
length: " + sorted.length);<br>
} catch (Exception ex) {<br>
throw new RuntimeException(ex);<br>
}<br>
});<br>
<br>
primaryStage.setScene(new Scene(new VBox(table,
loadManyBtn, reduceBtn, printBtn), 600, 400));<br>
primaryStage.show();<br>
}<br>
<br>
private static Object getFieldValue(Object object,
String fieldName) throws Exception {<br>
Field field =
object.getClass().getDeclaredField(fieldName);<br>
field.setAccessible(true);<br>
return field.get(object);<br>
}<br>
}</div>
<div dir="ltr" class="gmail_default" style="font-family: monospace;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: monospace;"><br>
</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;">Kind Regards,</div>
<div dir="ltr" class="gmail_default" style="font-family: verdana, sans-serif;">Cormac</div>
</blockquote>
</div>
</div>
</blockquote>
<br>
</body>
</html>