在每次场景变换时,内存的使用会增加并且永远不会“清理”,如果我来回穿过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();
可以帮助,但没有任何效果。我试图让所有对象变为null并调用它来尝试释放RAM但没有效果:
在这种情况下调用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);
});
});
}
这并没有影响记忆中的任何东西,它只会使场景的交换“窒息”而且更多。
有没有人知道如何在没有这种不必要的“堆积”的情况下改变场景?
编辑:啊,另一个有趣的一点,在使用过程中使用内存容易从1gb,但如果我使用一些ram清洁程序,它会低于100mb。
之前:
后:
悠久的历史简介:它不是关于你的代码,而是关于Java如何工作。 JavaFX通常需要更多内存,它会消耗更多内存,因为默认情况下,即使触发垃圾回收,Java也不会将内存返回给您的系统,因此如果JavaFX程序需要大量内存来处理但是可以释放之后,JRE继续保持最大内存水平并且垃圾收集器将不经常被触发,因为有太多可用的未使用内存,但是,你可以改变JVM行为,如何分配内存,它是如何分配的释放,当GC被触发时,请参阅Performance Tuning Guide