Optimizing memory leakage in JavaFX

java, javafx-8

Solution

There is a memory leak in JavaFX with Mesa >=11.0 (meaning any up to date Linux distribution). JavaFX developers say it's a bug in Mesa, but I couldn't find a bug report in Mesa (nor could I file one, as I don't know how to reproduce it outside of JavaFX). The only solutions as of now are - 1. Use an older Linux (the key is having Mesa 10 or lower) 2. Use an NVidia GPU - they have their own OpenGL implementation and don't rely on Mesa. 3. Use Windows.

Update (November 2016) This issue seems to have been resolved in newer versions of Mesa and/or X.org. Updating to Mesa 13.0 and X.org >=1.18.4 should solve this issue.

Related links:

- openjfx-dev discussion thread.

- reddit discussion.

- Mesa discussion.

- Related SO post: JavaXF 8 ProgressBar and ProgressIndicator with process=-1 memory leak on Linux

Problem

I have written a piece of code, to make letters appear and fly as I write them. The problem it consumes a lot of memory. I already optimized it a little bit by - Sharing the `path` object and update its parameters in listeners. - Calling gc each time a new letter is printed But it still uses a lot of memory, so any ideas about how to reduce its memory utilization ? Thanks in advance. ``` 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)); } } ``` EDIT #1 OS: Arch Linux 64-bit Platform: Intel i7-3rd generation, 8 GB ram IDE : Intellij JDK : 1.8.0_102 Proof of leak : After typing around 100 chars it jumped from 50 MB to 1.3 GB EDIT #2 I have checked Heap size using jvisualvm and it indicates that the Heap expands greatly but the used portion don't exceed ~50 MB

Original source