JavaFX-垃圾收集无法清理对象
我一直在试图找出如何处理我正在开发的JavaFX应用程序中的内存泄漏。我使用以下代码使用FX8测试内存行为:JavaFX-垃圾收集无法清理对象,java,memory-leaks,javafx,garbage-collection,Java,Memory Leaks,Javafx,Garbage Collection,我一直在试图找出如何处理我正在开发的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.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);
}
}
每当按下空格键时,root
的子项将被清除,一个新的矩形将附加到root
这段代码的问题是,随着空间被反复压缩,Java应用程序使用的内存量不断增加。即使应用程序在一段时间后处于空闲状态,应用程序使用的内存量也不会减少
我的印象是矩形对象应该被垃圾收集,但内存量并没有减少。这是JavaFX的问题,还是Java垃圾收集有什么我不知道的地方
编辑:使用
System.gc()
在@AlmasB的回答之后,我向回调添加了一个System.gc()
调用,这样每当按下空格时,建议gc执行垃圾收集
YourKit显示垃圾收集确实正在进行,事实上,正如YourKit所示,使用的堆和非堆内存量在一段时间后稳定下来,即使空间被反复压缩
TLDR:即使GC正在执行其工作,并且YourKit报告内存稳定,应用程序的内存消耗也会像活动监视器报告的那样逐渐增加。那么这是活动监视器的问题吗?Java中的垃圾收集并不意味着在没有强引用的情况下每个对象都超出范围后进行清理。当矩形对象不再可访问时,即清除根子对象时,该对象仅被标记为垃圾收集,但仍保留在内存中。你可以阅读更多的一般信息。所以从技术上讲,根据JVM环境的不同,GC甚至可能不会在应用程序的生命周期内运行,因为有足够的内存来分配新对象
如果您仍然认为存在内存泄漏,我建议您在担心JavaFX或GC可能存在错误之前,使用VisualGC之类的适当分析工具。Java中的垃圾收集并不意味着在没有强引用的情况下每个对象都超出范围后进行清理。当矩形对象不再可访问时,即清除根子对象时,该对象仅被标记为垃圾收集,但仍保留在内存中。你可以阅读更多的一般信息。所以从技术上讲,根据JVM环境的不同,GC甚至可能不会在应用程序的生命周期内运行,因为有足够的内存来分配新对象
如果您仍然认为存在内存泄漏,我建议您在担心JavaFX或GC可能存在错误之前,使用VisualGC之类的适当分析工具。Java中的垃圾收集并不意味着在没有强引用的情况下每个对象都超出范围后进行清理。当矩形对象不再可访问时,即清除根子对象时,该对象仅被标记为垃圾收集,但仍保留在内存中。你可以阅读更多的一般信息。所以从技术上讲,根据JVM环境的不同,GC甚至可能不会在应用程序的生命周期内运行,因为有足够的内存来分配新对象
如果您仍然认为存在内存泄漏,我建议您在担心JavaFX或GC可能存在错误之前,使用VisualGC之类的适当分析工具。Java中的垃圾收集并不意味着在没有强引用的情况下每个对象都超出范围后进行清理。当矩形对象不再可访问时,即清除根子对象时,该对象仅被标记为垃圾收集,但仍保留在内存中。你可以阅读更多的一般信息。所以从技术上讲,根据JVM环境的不同,GC甚至可能不会在应用程序的生命周期内运行,因为有足够的内存来分配新对象
如果您仍然认为存在内存泄漏,我建议您在担心JavaFX或GC可能存在错误之前使用VisualGC之类的适当分析工具。因此,如果运行GC,则应用程序使用的内存应该减少,这应该反映在任务管理器/活动监视器中,是吗?当GC运行时,这意味着JVM从其总内存中获得更多的空闲内存,而不是操作系统。只有当JVM本身将内存还给操作系统时,才会反映出这一点,这种情况很少发生。将本机内存从操作系统分配到JVM被认为是一项昂贵的操作。因此,JVM通常会保留内存,直到OS完全需要内存为止。不管怎么说,以前都是这样,因此如果运行GC,那么应用程序使用的内存应该减少,这应该反映在任务管理器/活动监视器中,是吗?当GC运行时,意味着JVM从其总内存中获得更多的可用内存,而不是操作系统。只有当JVM本身将内存还给操作系统时,才会反映出这一点,这种情况很少发生。将本机内存从操作系统分配到JVM被认为是一项昂贵的操作。因此,JVM通常会保留内存,直到OS完全需要内存为止。不管怎么说,以前都是这样,因此如果运行GC,那么应用程序使用的内存应该减少,这应该反映在任务管理器/活动监视器中,是吗?当GC运行时,意味着JVM从其总内存中获得更多的可用内存,而不是操作系统。只有当JVM本身将内存还给操作系统时,才会反映出这一点,这种情况很少发生。将本机内存从操作系统分配到JVM被认为是一项昂贵的操作。因此,JVM通常会保留内存,直到OS完全需要内存为止。不管怎么说,以前都是这样,所以如果运行GC,那么应用程序使用的内存