我一直在努力弄清楚如何处理我正在处理的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
的孩子都会被清除,并且root
会附加一个新的矩形。
此代码的问题在于,当重复按下 SPACE 时,Java应用程序使用的内存量不断增加。即使应用程序在一段时间后处于空闲状态,应用程序使用的内存量也不会减少。
我的印象是Rectangle对象应该被垃圾收集,但内存量不会减少。这是JavaFX的问题,还是我不知道的Java垃圾收集问题?
编辑:使用System.gc()
和YourKit
按照@ AlmasB的回答,我在回调中添加了System.gc()
调用,这样每当按下 SPACE 时,建议GC执行垃圾回收。 / p>
YourKit显示垃圾收集确实正在进行,事实上,堆的数量和如YouKit所示,使用的非堆内存会在一段时间后稳定,即使重复按下 SPACE 。
TLDR:即使GC正在执行其工作且YourKit报告稳定内存,应用程序的内存消耗也会继续逐渐增加,如Activity Monitor所报告的那样。这是活动监视器的问题吗?