启用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;
}
}