Я пытался выяснить, как бороться с утечками памяти в приложении JavaFX, над которым я работаю. Я использовал следующий код, используя FX8, чтобы проверить поведение памяти:JavaFX - сбор мусора не удается очистить объекты
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
«s дети очищаются и новый прямоугольник крепится к root
.
Проблема с этим кодом заключается в том, что при повторном нажатии на кнопку SPACE объем памяти, используемой приложением Java, увеличивается. Даже когда приложение остается бездействующим в течение некоторого времени после этого, объем памяти, используемой приложением, не уменьшается.
Мое впечатление, что объекты Rectangle должны были быть собраны мусором, и при этом объем памяти не уменьшается. Это проблема с JavaFX, или есть что-то о сборке мусора Java, о котором я не знаю?
EDIT: Использование System.gc()
и YourKit
Этот @ ответ AlmasB, я добавил System.gc()
вызов функции обратного вызова, таким образом, что всякий раз, когда ПРОСТРАНСТВО нажата, GC, предлагается выполнить мусор коллекция.
YourKit показывает, что мусорные сборники действительно ведутся, а на самом деле, количество Heap & используется Non-динамической памяти, как показано YourKit, стабилизируется через некоторое время, даже когда ПРОСТРАНСТВА повторно нажата.
TLDR: даже когда GC выполняет свою работу, а информация о сохранении памяти в ItKit сохраняется, расход памяти приложения продолжает расти постепенно, как сообщает Activity Monitor. Это проблема с Activity Monitor?
Итак, если GC _is_ запускается, то память, используемая приложением, должна уменьшаться, и это должно быть отражено в диспетчере задач/мониторе активности, да? – peco
Когда GC запускается, это означает, что JVM получает больше свободной памяти из своей общей памяти, а не ОС. Это будет отражено только в том случае, если сам JVM возвращает память ОС, что случается редко. Распределение собственной памяти от ОС до JVM считается дорогостоящей операцией. Следовательно, как правило, JVM будет хранить память до себя, пока ОС не понадобится память. В любом случае это имело место – AlmasB