At each scene change, the use of memory increases and it is never "cleaned", if I go back and forth through 2 screens, the same happens several times, every time I enter the same screen it increases the use, only the first screen for the second that we can see that the use diminishes, is where it is marked in the graphic in red.
Notice that garbage collection only increases:
To change scenes I use the following code:
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);
}
});
}
After searching I saw that System.gc();
could help but have no effect.
I tried to make all the objects go to null and call it to try to release RAM but without effect:
Call changeStage(this, stackPane, "Title", "Url");
, This
in this case is the class itself that implements the 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);
});
});
}
This did not influence anything in the memory, it only made the exchange of scenes "choked up" and a bit more.
Does anyone know how I can actually do to change scene without this unnecessary "heaping"?
Edit: Ah, another interesting point, this use of memory in the course of use goes from 1gb easy, but if I use some ram cleaning program, it goes below 100mb.
Before:
After: