JDK-8128885 : Memory leak in ListView: listeners are not removed
  • Type: Bug
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: fx2.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2011-08-30
  • Updated: 2015-06-17
  • Resolved: 2012-08-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8Fixed
Related Reports
Relates :  
Relates :  
Description
ListViewMemTest (attached) run in static mode and 16mb of heap fails with OOM after ~18,000 iterations.
The reason is because listeners are not removed.
staticListViewData -> observers -> elementData array has 297,868 elements (WeakListChangeListener) 
at the time the test fails with OOM. See attached ListView_heap.jpg as well.

The test just creates new ListView object with static elements (created at the beginning of the test)
on each pulse. ListView object created on previous pulse is removed before new one is created.
So, only one ListView object exists at any moment of time.

Steps to run the test:
> java -Xmx16m -verbose:gc -XX:+HeapDumpOnOutOfMemoryError -cp "..." ListViewMemTest -mode static

There is no such memory issue in case the test is run in dynamic mode (-mode dynamic).




Comments
Changeset: 6ca66c53de08 Author: jgiles Date: Fri Aug 24 09:42:03 2012 +1200 URL: http://jfxsrc.us.oracle.com/javafx/8.0/scrum/controls/rt/rev/6ca66c53de08
23-08-2012

The issue is in ListViewBehavior - the following code around line 289 is added to the items list, but never removed: control.itemsProperty().addListener(new ChangeListener<ObservableList<T>>() { @Override public void changed(ObservableValue ov, ObservableList oldValue, ObservableList newValue) { if (oldValue != null) { oldValue.removeListener(itemsListListener); } if (newValue != null) { newValue.addListener(itemsListListener); } } }); To resolve this issue we really need a proper cleanup routine for controls when they are garbage collected so that the skin and behavior code may also clean up.
31-07-2012

SQE - ok to defer
01-09-2011

This does not seem to be a serious leak. Would suggest deferral.
31-08-2011

it seems to be not the case. Running with -verbose:gc shows that "Full GC" constantly occurs but WeakListChangeListeners are not cleared. Perhaps there are strong references to them as well (I didn't analyze it).
30-08-2011

It is probable that these listeners are all WeakListChangeListeners that will GC themselves when they are next called, as the actual, wrapped listener will have likely already been GC'd.
30-08-2011

One of the latest graphics-scrum builds #2802 (Aug 30) was used to reproduce the issue.
30-08-2011

Filing this issue as critical till initial evaluation is done. We can degrade the priority and target it to update release based on evaluation and the fact how it is possible users will face the same issue.
30-08-2011