При каждом изменении сцены использование памяти увеличивается, и она никогда не «очищается», если я перехожу назад и вперед через 2 экрана, то же самое происходит несколько раз, каждый раз, когда я вхожу на тот же экран, это увеличивает использование, только первый экран для второго, который мы видим, что использование уменьшается, где он отмечен на рисунке красным.
Обратите внимание, что сбор мусора только увеличивается:
Для смены сцен я использую следующий код:
public void changeStage(Parent event, String title, String url){
Platform.runLater(() -> {
try {
Parent loader = FXMLLoader.load(getClass().getResource("/gro/admin/java/" + url));
event.getScene().setRoot(loader);
} catch (IOException ex) {
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
После поиска я увидел, что System.gc();
может помочь, но безрезультатно.
Я попытался заставить все объекты перейти в нуль и вызвать его, чтобы попытаться освободить ОЗУ, но безрезультатно:
Call changeStage(this, stackPane, "Title", "Url");
, This
в данном случае это сам класс, который реализует Initializable
public void changeStage(Object obj, Parent event, String title, String url){
Platform.runLater(() -> {
try {
nullAll(obj, event);
Parent loader = FXMLLoader.load(getClass().getResource("/gro/admin/java/" + url));
event.getScene().setRoot(loader);
} catch (IOException ex) {
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
private static void nullAll(Object obj, Parent root){
ObservableList<Node> nodes = getAllViews(root);
nodes.forEach(node -> node = null);
nodes.clear();
nodes = null;
if(root instanceof StackPane){
((StackPane) root).getChildren().clear();
root = null;
}else{
root = null;
}
obj = null;
System.gc();
}
private static ObservableList<Node> getAllViews(Parent root) {
ObservableList<Node> nodes = FXCollections.observableArrayList();
addAllDescendents(root, nodes);
return nodes;
}
private static void addAllDescendents(Parent parent, ObservableList<Node> nodes) {
parent.getChildrenUnmodifiable().stream().map((node) -> {
nodes.add(node);
return node;
}).map((node) -> {
if (node instanceof Parent){
addAllDescendents((Parent) node, nodes);
}
return node;
}).map((node) -> {
if(node instanceof ScrollPane){
addAllDescendents((Parent) ((ScrollPane) node).getContent(), nodes);
nodes.add(((ScrollPane) node).getContent());
}
return node;
}).map((node) -> {
if(node instanceof TabPane){
((TabPane) node).getTabs().forEach((t) -> {
addAllDescendents((Parent) ((Tab) t).getContent(), nodes);
});
}
return node;
}).filter((node) -> (node instanceof JFXTabPane)).forEachOrdered((node) -> {
((JFXTabPane) node).getTabs().forEach((t) -> {
addAllDescendents((Parent) ((Tab) t).getContent(), nodes);
});
});
}
Это не повлияло ни на что в памяти, оно только сделало обмен сценами "захлебнувшимися" и немного больше.
Кто-нибудь знает, как я могу на самом деле изменить сцену без этой ненужной "кучи"?
Редактировать: Ах, еще один интересный момент, это использование памяти в процессе использования идет от 1 ГБ легко, но если я использую какую-то программу очистки оперативной памяти, она идет ниже 100 МБ.
До:
После того, как: