【问题标题】:Optimizing memory leakage in JavaFX优化 JavaFX 中的内存泄漏
【发布时间】:2017-03-06 20:20:24
【问题描述】:

我写了一段代码,让字母在我写的时候出现并飞起来。它消耗大量内存的问题。

我已经优化了一点

  • 共享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 generation,8 GB 内存 IDE:Intellij JDK:1.8.0_102

泄漏证明:输入大约 100 个字符后,它从 50 MB 跃升至 1.3 GB


编辑#2

我使用 jvisualvm 检查了堆大小,它表明堆扩展很大,但使用的部分不超过 ~50 MB

【问题讨论】:

  • 我可以用 50MB 运行你的应用程序,你怎么说它消耗大量内存?
  • 继续写几个字母,内存就会增加。
  • 有很多关于如何查找内存泄漏的问答;例如搜索“[java] 查找内存泄漏”。 (本机内存泄漏有点棘手......)但首先你需要明确的证据表明存在 >>is
  • “每次打印一个新字母时调用 gc”:乱搞垃圾收集器通常是个坏主意。让它在不干扰的情况下完成它的工作,它为此进行了优化。
  • @ShadyAtef - Mesa >=11.0(意味着任何最新的 Linux 发行版)的 JavaFX 中存在内存泄漏。 JavaFX 开发人员说这是 Mesa 中的一个错误,但我在 Mesa 中找不到错误报告(我也无法提交,因为我不知道如何在 JavaFX 之外重现它)。目前唯一的解决方案是 - 1. 使用较旧的 Linux(关键是 Mesa 10 或更低版本); 2. 使用 NVidia GPU——他们有自己的 OpenGL 实现,不依赖 Mesa。 3. 使用 Windows。

标签: java javafx-8


【解决方案1】:

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

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

相关链接:

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 您是否也升级了 X.org?仅更新 Mesa 是不够的,也没有为我解决问题,但是通过更新 X.org mesa 问题解决了。
    • 我已经升级了整个系统
    • 如果您的系统(大概是 Linux 发行版?)没有打包新版本,升级整个系统将无法解决问题。验证您的确切版本。
    猜你喜欢
    • 1970-01-01
    • 2013-08-16
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 2017-01-27
    • 1970-01-01
    相关资源
    最近更新 更多