JDK-8203345 : Memory leak in VirtualFlow when screen reader is enabled
  • Type: Bug
  • Component: javafx
  • Sub-Component: accessibility
  • Affected Version: 8u192,9,10,openjfx11
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2018-05-14
  • Updated: 2021-02-26
  • Resolved: 2018-07-06
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 Other
8u301Fixed openjfx11Fixed
Related Reports
Duplicate :  
Relates :  
Description
A DESCRIPTION OF THE PROBLEM :
In class VirtualFlow there exists a private method getPrivateCell(int) which at the end could add a new cell to an array called privateCells. Elements from this array are never removed.
An element could be e. g. a TableRow (via TableView) which could use hundreds of KB of memory. Therefore if lots of such elements are added this could lead to an OutOfMemory error.

The call hierarchy of this method shows that the method getPrivateCell(int) is only called via the method queryAccessibleAttribute(AccessibleAttribute, Object...). This could imply that this issue is only relevant when Accessability is turned on.

According to the source code this could affect the controls TableView, TreeTableView and ListView.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a TableView. Use a Screen-Reader (e. g. narrator under Windows 10) to turn on Accessibility for the window. That Accessibility is turned on can be verified via the property Platform.accessibilityActiveProperty().

When adding new rows to the table under certain workflows (e. g. click on row, sort, etc.) a TableRow element is added to an internal List privateCells in VirtualFlow in method getPrivateCell().

With a debugger (setting a breakpoint at line where element is added to privateCells) or by creating a heap dump one can verify that elements get added to the List privateCells. However these elements are never removed as one can verify be reading the source code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
TableRow elements should be removed from privateCells after some time.
Maybe in the method releaseAllPrivateCells()?
ACTUAL -
TableRow elements are never removed from privateCells.

CUSTOMER SUBMITTED WORKAROUND :
As a workaround one can set the system property "glass.accessible.force" to "false".
This turns off Accessability and therefore does not cause the memory leak. Note that Accessability is turned on by default only on Mac 10.9 and Windows 7 or greater according to notes in com.sun.glass.ui.View.


Comments
Changeset: 7bdf2d46a9df Author: kcr Date: 2018-07-05 21:21 +0200 URL: http://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/7bdf2d46a9df 8203345: Memory leak in VirtualFlow when screen reader is Reviewed-by: kcr, pkbalakr Contributed-by: bernhard.lutzmann at gmail.com
06-07-2018

Code review is happening here: https://github.com/javafxports/openjdk-jfx/pull/78
29-05-2018

I am able to reproduce this issue on Windows 10 with latest jdk-11-178(nightly), screen reader:Narrator.
18-05-2018

This is also being tracked on GitHub: https://github.com/javafxports/openjdk-jfx/issues/77
17-05-2018

Submitter provided github link for this issue https://github.com/javafxports/openjdk-jfx/issues/77, where more info is available for reproducing the issue. When checked in jdk-11-178(nightly), issue is reproducible. With each click of 'Add' button, privateCells list size increases. When workaround is enabled, privateCells size does not change.
17-05-2018

Not able to reproduce this issue, with the provided workflows. Checked in Netbeans with JDK 10. On Windows with screen reader (Narrator) is turned ON or OFF, in both cases VirtualFLow::getPrivateCell() gets called from TableViewSkinBase::queryAccessibleAttribute(...) function. But debugger never reaches till 'privateCells.add(cell);', it gets returned much before this in first 'if' loop :: // If there are cells, then we will attempt to get an existing cell if (! cells.isEmpty()) { // First check the cells that have already been created and are // in use. If this call returns a value, then we can use it cell = getVisibleCell(index); if (cell != null) { // Force the underlying text inside the cell to be updated // so that when the screen reader runs, it will match the // text in the cell (force updateDisplayedText()) cell.layout(); return cell; } } With the workflow suggested by reporter, like clicking on a row, getPrivateCell() function gets called, but the privateCells list size does not change/gets incremented. Requested Submitter for proper workflow, with which the issue is always reproducible.
16-05-2018