Я пытался выяснить, почему приложение на основе JavaFX, над которым я работаю, использует столько памяти. Я заметил, что память поднималась каждый раз, когда я открывал новую вкладку в приложении, и не был GC после того, как я закрыл вкладку. Я бы продолжал открывать и закрывать вкладки, пока в конце концов не закончилось память и не разбился.Закрытие вкладок JavaFX не освобождает память из ArrayLists и TableViews на этой вкладке
Итак, я написал и попробовал очень простую программу и графический интерфейс. Код ниже. Я обнаружил, что если я установил элементы в TableView равными null, очистил ArrayList и создал новый ArrayList с тем же именем переменной, только тогда это будет GC.
Это обычное поведение для Java и/или JavaFX? Нормально, что он не «уничтожит» те объекты на вкладке после закрытия вкладки? Ошибка с Java 8/FX?
import java.util.ArrayList;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Orientation;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableView;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class TabTest extends Application {
ArrayList<String> _list;
@Override
public void start(Stage primaryStage) {
SplitPane split = new SplitPane();
split.setOrientation(Orientation.VERTICAL);
HBox window = new HBox();
HBox top = new HBox(20);
HBox bottom = new HBox(20);
Group group = new Group();
TabPane tabPane = new TabPane();
Button btn = new Button("Create Tab");
top.getChildren().add(btn);
bottom.getChildren().add(tabPane);
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
createTabAndList(tabPane);
}
});
split.getItems().addAll(top,bottom);
window.getChildren().add(split);
group.getChildren().add(window);
Scene scene = new Scene(group);
split.prefWidthProperty().bind(scene.widthProperty());
split.prefHeightProperty().bind(scene.heightProperty());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public void createTabAndList(TabPane tabPane){
_list = new ArrayList<String>();
for(int i = 0; i < 10000000; i++){
_list.add("Test Test Test");
}
TableView<String> tb1 = new TableView<String>();
tb1.setItems(FXCollections.observableArrayList(_list));
Tab tab = new Tab("Tab1");
tab.setContent(tb1);
tabPane.getTabs().add(tab);
tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.SELECTED_TAB);
tab.setOnClosed(new EventHandler<Event>() {
@Override
public void handle(Event arg0) {
tb1.setItems(null);
_list.clear();
_list = new ArrayList<String>();
}
});
}
}
Как правило, Java не уничтожает * ничего *, о котором вы все еще имеете ссылку. – RealSkeptic
Зачем мне/приложение иметь ссылку на него, если вкладка закрыта? – user1795832
Поскольку элемент GUI визуально доступен или нет, он не имеет ничего общего с объектами, которые его создают. Что делать, если вы хотите, например, выполнить «закрытие закрытой вкладки»? – RealSkeptic