A DESCRIPTION OF THE PROBLEM :
There is still a memory leak in the scene when it comes to MouseHandler. There already is a bugfix that considers most of the use cases (see links down below) but one scenario is missing:
If you start dragging a cell of a tableview the fullPDRTmpTargetWrapper field of the scene keeps holding on to the reference of the tableview even when its gone and the GC was triggered.
https://github.com/openjdk/jfx/pull/448
https://bugs.openjdk.java.net/browse/JDK-8264330
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- drag a cell
- push button 'Remove Pane'
- trigger GC
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
no remaining reference to the tableview
ACTUAL -
fullPDRTmpTargetWrapper still has a reference to the tableview
---------- BEGIN SOURCE ----------
package com.arm.ablex.client.fx.main;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MemoryLeak extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Button buttonRemove = new Button("Remove Pane");
VBox box = new VBox(buildTableView(), buttonRemove);
Scene scene = new Scene(box);
buttonRemove.setOnAction(event -> scene.setRoot(new Pane()));
stage.setWidth(1000);
stage.setScene(scene);
stage.show();
}
private TableView buildTableView() {
TableView<String> tableView = new TableView();
TableColumn<String, String> column = new TableColumn<>("column");
column.setCellValueFactory(param -> new SimpleStringProperty(param.getValue()));
column.setCellFactory(param -> {
TableCell<String, String> cell = new TableCell<>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setText(item);
setOnDragDetected(event -> {
startFullDrag();
System.out.println("this causes memory leak");
});
} else {
setText(null);
setOnDragDetected(null);
}
}
};
return cell;
});
tableView.getColumns().add(column);
tableView.getItems().addAll("item1", "item2", "item3");
return tableView;
}
}
---------- END SOURCE ----------
FREQUENCY : always