启用 TableMenu 时,TreeTableView 出现内存泄漏。重现的步骤很简单。我已经做了一些研究为什么会发生这种情况,但会留给这里的专家来阐明。
使用 -Xmx 256m 运行嵌入式代码以减少等待时间。我正在使用 JDK 1.8.0_121
这两个步骤必须按顺序执行。
- 单击右上角的表菜单菜单按钮(+)一次,无需选择任何菜单项。
然后单击DYNAMIC列上的(X)(给 OOM 几秒钟)
package hellofx; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableCell; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableView; import javafx.stage.Stage; public class TreeTableMemoryLeak extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { TreeTableView<Object> otable = buildTableView(); Platform.runLater(()->{ Scene scene = new Scene(otable,otable.getWidth(),otable.getHeight()); stage.setScene(scene); stage.show(); }); } private TreeTableView<Object> buildTableView() { TreeTableView<Object> table = new TreeTableView<>(); TreeTableColumn<Object, String> indexCol = new TreeTableColumn<>("Index"); indexCol.setCellFactory(column -> { return new TreeTableCell<Object, String>() { @Override protected void updateItem(String item, boolean empty) { setText(String.valueOf(getIndex())); } }; }); TreeTableColumn<Object, String> dynCol = new TreeTableColumn<>("DYNAMIC"); dynCol.setGraphic(new Button("X"){ { //ATTENTION 3 (On click of X remove all columns except first column) setOnAction((e)->dynCol.getColumns().removeIf(c->c!=dynCol.getColumns().get(0))); } }); //ATTENTION 1 table.setTableMenuButtonVisible(true); //ATTENTION 2 (39 is the magic number anything higher it will OOM on my device I have total 6G physical.) for(int i=0;i<39;i++){ dynCol.getColumns().add(new TreeTableColumn<>(String.valueOf(i))); } table.getColumns().addAll(indexCol,dynCol); table.setEditable(true); table.setRoot(new TreeItem<Object>()); return table; } }