当我在JavaFX项目中动态更新我的表时,我有很多内存泄漏。我有三种方法。按下按钮CreateModel后启动。然后在这个方法的最后,我调用initTable()和initData()init,并将数据放入表中。 当我按下CreateModel几次时,我程序的内存使用量从~100mb增加到250-350mb。当我评论这两种方法时,程序在没有更新表的情况下工作,我没有内存泄漏。
@FXML
protected void handleButtonCreateAction(ActionEvent event) throws Throwable {
processes = Integer.parseInt(textFieldProcesses.getText());
resources = Integer.parseInt(textFieldResources.getText());
banker.init(resources, processes, Integer.parseInt(textFieldMaxResourceCount.getText()));
if(myThread == null) {
myThread = new MyThread(this, banker);
} else {
myThread.stop();
myThread.finalize();//Bug fix
myThread = null;
myThread = new MyThread(this, banker);
}
autoModeCheckBox.setSelected(false);
myThread.setAutoMode(false);
//TODO: bug when create sleep time from slider is not in Thread
initColumns();
initData();
}
void initColumns() {
mainTableView.getColumns().clear();
mainTableView.getColumns().add(createProcessColumn());
for (int i = 1; i <= resources; i++) {
mainTableView.getColumns().add(newResourceColumn(i));
}
}
void initData() {
tableData = banker.genRows();
mainTableView.setItems(tableData);
ObservableList<TableColumn> headerColumnsList = mainTableView.getColumns();
for(int i = 1; i < headerColumnsList.size(); i++) {
TableColumn resourceUsageColumn = (TableColumn) headerColumnsList.get(i).getColumns().get(0);
resourceUsageColumn.setText(String.valueOf(banker.getResourceUsage(i-1)) + "/" + String.valueOf(banker.getResourceCount(i-1)));
}
}
void clearTable() {
if (tableData != null) {
tableData.clear();
//mainTableView.setItems(tableData);
}
}
private TableColumn createProcessColumn() {
TableColumn containerColumn = new TableColumn();//containerColumn
TableColumn subContainerColumn = new TableColumn();//subContainerColumn
TableColumn processColumn = new TableColumn("Process");//processColumn
processColumn.setMinWidth(TABLE_PROCESSES_COLUMN_WIDTH);
processColumn.setResizable(false);
processColumn.setSortable(false);
/*processColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList,String>,ObservableValue<String>>() {
public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(0).toString());//number in param.getValue().get(number) pointed to row number of data in our List
}
});*/
processColumn.setCellFactory(new Callback<TableColumn, TableCell>() { //TODO: If use this type of set CellFactory you can't sort columns
@Override
public TableCell call(TableColumn p) {
return new TableCell() {
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
this.setStyle("-fx-background-color:lightgrey");
if (!isEmpty()) {
if (!banker.getWorkingProcesses().contains(this.getIndex()))
this.setStyle("-fx-background-color:darkgray");//if this process finished his work
setText(tableData.get(this.getIndex()).get(0).toString()); //getIndex return number of this cell in column
} else {//TODO: Bug fix
setText(null);
setStyle(null);
setEffect(null);
}
}
};
}
});
subContainerColumn.getColumns().add(processColumn);
containerColumn.getColumns().add(subContainerColumn);
return containerColumn;
}
private TableColumn newResourceColumn(final int index) {
TableColumn resourceColumn = new TableColumn("Resource" + String.valueOf(index));//resourceColumn
TableColumn resourceUsageColumn = new TableColumn("-/-");//TODO: rename
TableColumn allocationColumn = new TableColumn("Alloc");//allocationColumn
allocationColumn.setMinWidth(TABLE_COLUMN_WIDTH);
allocationColumn.setPrefWidth(TABLE_COLUMN_WIDTH);
allocationColumn.setMaxWidth(TABLE_COLUMN_WIDTH);
allocationColumn.setResizable(false);
allocationColumn.setSortable(false);
allocationColumn.setCellFactory(new Callback<TableColumn, TableCell>() {
@Override
public TableCell call(TableColumn p) {
return new TableCell() {
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
if (!banker.getWorkingProcesses().contains(this.getIndex())) { //if this process finished his work
this.setStyle(TABLE_CELL_FINISHED_COLOR);
this.setTextFill(Color.BLACK);
this.setEffect(null);
}
else if ((this.getIndex() == banker.getRequest().getProcess()) && (index == banker.getRequest().getResource()+1)) {//if this cell contained in request
this.setStyle(TABLE_ALLOC_CELL_SELECTED_COLOR);
this.setTextFill(Color.WHITE);
InnerShadow innerShadow = new InnerShadow();
innerShadow.setRadius(TABLE_CELL_SHADOW_RADIUS);
innerShadow.setColor(Color.gray(0, TABLE_CELL_SHADOW_OPACITY));
this.setEffect(innerShadow);
}
else {//if this cell not contained in request
this.setStyle(TABLE_ALLOC_CELL_COLOR);
this.setTextFill(Color.BLACK);
this.setEffect(null);
}
setText(tableData.get(this.getIndex()).get(index * 2 - 1).toString()); //getIndex return number of this cell in column
} else { //TODO: Bug fix
setText(null);
setStyle(null);
setEffect(null);
}
}
};
}
});