【发布时间】: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
【问题讨论】:
-
我可以用 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。