RAM Excessive Spending - JavaFX

问题: 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 th...

问题:

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.

enter image description here

Notice that garbage collection only increases:

enter image description here

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:

enter image description here

After:

enter image description here


回答1:

Long history short: It is not about your code, it is about how Java works. JavaFX needs more memory in general, it will consume more memory as it needs to, As a default Java does not return memory back to your system even if you trigger the garbage collection, so if JavaFX program needs a lot of memory to process but frees it afterwards, the JRE continues to hold the maximum level of memory for ever and the Garbage Collector will be triggered less often, because there is so much free unused memory, nevertheless, you can change the JVM behavior, how memory is allocated, how it's freed and when the GC is triggered, please see Performance Tuning Guide

  • 发表于 2019-03-17 14:56
  • 阅读 ( 302 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除