优化JavaFX中的内存泄漏

时间:2016-10-24 22:56:14

标签: java javafx-8

我写了一段代码,以便在我写作时使字母显示和飞行。它消耗了大量内存的问题。

我已经通过

稍微优化了一下
  • 共享path对象并在侦听器中更新其参数。
  • 每次打印新信件时调用gc

但它仍然使用了大量内存,所以关于如何降低内存利用率的任何想法?

提前致谢。



    package sample;

    import javafx.animation.PathTransition;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.LineTo;
    import javafx.scene.shape.MoveTo;
    import javafx.scene.shape.Path;
    import javafx.scene.text.Font;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    import javafx.util.Duration;

    public class Main extends Application {

        public static void main(String[] args) {
            launch(args);
        }

        @Override
        public void start(Stage primaryStage) throws Exception {
            Pane root = new Pane();
            Scene scene = new Scene(root);
            root.setCache(false);
            primaryStage.setTitle("Hello World");
            primaryStage.setScene(scene);


            Path path = new Path();
            root.widthProperty().addListener((observableValue, oldSceneWidth, newSceneWidth) -> SetPathElements(path, root));
            root.heightProperty().addListener((observableValue, oldSceneWidth, newSceneWidth) -> SetPathElements(path, root));


            Duration duration = Duration.millis(1000);

            scene.setOnKeyPressed(event -> {
                System.gc();

                Text textNode = new Text(event.getText());
                textNode.setFont(Font.font(50));
                textNode.setFill(Color.ORANGE);
                root.getChildren().add(textNode);


                PathTransition pathTransition = new PathTransition();
                pathTransition.setDuration(duration);
                pathTransition.setPath(path);
                pathTransition.setCycleCount(1);

                pathTransition.setNode(textNode);
                pathTransition.setOnFinished(event1 -> {
                    root.getChildren().remove(textNode);
                    pathTransition.setNode(null);
                    pathTransition.setPath(null);
                    textNode.setFont(null);
                    textNode.setFill(null);
                });
                pathTransition.play();


            });
            primaryStage.show();
        }

        private void SetPathElements(Path path, Pane root) {
            path.getElements().clear();
            double w = root.getWidth();
            double h = root.getHeight();
            path.getElements().add(new MoveTo(w / 2, h));
            path.getElements().add(new LineTo(w / 2, -40));
        }
    }


编辑#1

操作系统:Arch Linux 64位 平台:Intel i7-3rd一代,8 GB内存 IDE:Intellij JDK:1.8.0_102

泄漏证明:在输入大约100个字符后,它从50 MB跳到1.3 GB Memory leakage proof

编辑#2

我已经使用jvisualvm检查了堆大小,它表明堆扩展很大但是使用的部分不超过~50 MB enter image description here

2 个答案:

答案 0 :(得分:5)

JavaFX中存在内存泄漏,Mesa> = 11.0(意味着任何最新的Linux发行版)。 JavaFX开发人员说它是Mesa中的一个错误,但我在Mesa中找不到错误报告(也不能提交一个错误报告,因为我不知道如何在JavaFX之外重现它)。 目前唯一的解决方案是 -
 1.使用较旧的Linux(密钥是Mesa 10或更低版本)
 2.使用NVidia GPU - 他们有自己的OpenGL实现,不依赖于Mesa  3.使用Windows。

更新(2016年11月)
这个问题似乎已在较新版本的Mesa和/或X.org中得到解决。更新到Mesa 13.0和X.or​​g> = 1.18.4 应该解决此问题。

相关链接:

答案 1 :(得分:0)

升级到Mesa 13.0.4并不能解决问题,但有一种解决方法。

如果程序使用-Dprism.order=j2d-Dprism.order=sw VM参数运行,则JavaFX渲染引擎不使用OpenGL,并且不会发生泄漏。当然,在这种情况下,应用程序性能会显着下降。