JavaFX - 垃圾收集无法清理 objects
JavaFX - Garbage collection fails to clean up objects
我一直在努力弄清楚如何处理我正在处理的 JavaFX 应用程序中的内存泄漏。我使用以下代码使用 FX8 来测试内存行为:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Main extends Application {
public int count = 0;
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 500, 500, Color.BLACK);
Rectangle r = new Rectangle(25,25,250,250);
r.setFill(Color.BLUE);
root.getChildren().add(r);
scene.addEventHandler(KeyEvent.KEY_RELEASED, event -> {
if (event.getCode() == KeyCode.SPACE) {
event.consume();
count++;
Rectangle r2 = new Rectangle(25, 25, 250, 250);
r2.setFill(Color.BLUE);
root.getChildren().clear();
root.getChildren().add(r2);
}
});
stage.setTitle("JavaFX Scene Graph Demo");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
每当按下 SPACE 时,root
的 children 就会被清除,并在 root
上附加一个新的矩形.
此代码的问题在于,随着 SPACE 被反复按下,Java 应用程序使用的内存量不断增加。即使应用程序在一段时间后处于空闲状态,应用程序使用的内存量也不会减少。
我的印象是 Rectangle objects 应该被垃圾回收了,但内存量并没有减少。这是 JavaFX 的问题,还是关于 Java 垃圾收集的一些我不知道的事情?
编辑: 使用 System.gc()
和 YourKit
在@AlmasB 的回答之后,我添加了一个 System.gc()
回调调用,这样每当按下 SPACE 时,建议执行 GC垃圾回收。
YourKit 显示垃圾收集确实在进行,事实上,如 YourKit 所示,使用的堆和 Non-Heap 内存量在 SPACE被重复按下。
TLDR:即使 GC 正在执行它的工作并且 YourKit 报告内存稳定,应用程序的内存消耗也会继续逐渐增加,如 Activity 监视器所报告的那样。这是 Activity 监视器的问题吗?
我一直在努力弄清楚如何处理我正在处理的 JavaFX 应用程序中的内存泄漏。我使用以下代码使用 FX8 来测试内存行为:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Main extends Application {
public int count = 0;
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 500, 500, Color.BLACK);
Rectangle r = new Rectangle(25,25,250,250);
r.setFill(Color.BLUE);
root.getChildren().add(r);
scene.addEventHandler(KeyEvent.KEY_RELEASED, event -> {
if (event.getCode() == KeyCode.SPACE) {
event.consume();
count++;
Rectangle r2 = new Rectangle(25, 25, 250, 250);
r2.setFill(Color.BLUE);
root.getChildren().clear();
root.getChildren().add(r2);
}
});
stage.setTitle("JavaFX Scene Graph Demo");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
每当按下 SPACE 时,root
的 children 就会被清除,并在 root
上附加一个新的矩形.
此代码的问题在于,随着 SPACE 被反复按下,Java 应用程序使用的内存量不断增加。即使应用程序在一段时间后处于空闲状态,应用程序使用的内存量也不会减少。
我的印象是 Rectangle objects 应该被垃圾回收了,但内存量并没有减少。这是 JavaFX 的问题,还是关于 Java 垃圾收集的一些我不知道的事情?
编辑: 使用 System.gc()
和 YourKit
在@AlmasB 的回答之后,我添加了一个 System.gc()
回调调用,这样每当按下 SPACE 时,建议执行 GC垃圾回收。
YourKit 显示垃圾收集确实在进行,事实上,如 YourKit 所示,使用的堆和 Non-Heap 内存量在 SPACE被重复按下。
TLDR:即使 GC 正在执行它的工作并且 YourKit 报告内存稳定,应用程序的内存消耗也会继续逐渐增加,如 Activity 监视器所报告的那样。这是 Activity 监视器的问题吗?