Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8088175

[Text] Memory leak in JavaFX text drawing

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P3 P3
    • 9
    • 8u40, 9
    • javafx
    • Windows x64

      Isssue Description:
      It seems there's some rather big memory leaks in simply updating a label with new text, where resources are not released. We noticed a never-ending increase of heap size simply showing a clock in our application and then narrowed it down and created a very simple test case that shows the same behavior when attached to a Profiler.

      How to test:
      Run the test code, attach a Java Profiler (I used JProfiler and VisualVM, but any should be fine). When ready press the "Start" button in the test app. Let it run for a few 100 iterations then press stop. Hit "mark current" (or however your profiler helps you see deltas between runs), then press Start, Wait a bit, press Stop and then do a GC in the profiler. Do this a few times, and you'll see that a quite a few places are not letting go of resources (even if you wait a good long time after finishing the test to GC). The longer you wait when running the test, the higher the deltas. Hot spots in particular are:

      com.sun.javafx.text.TextRun[]
      com.sun.javafx.geom.Point2D
      com.sun.javafx.text.LayoutCache
      com.sun.javafx.text.TextLine
      com.sun.javafx.text.TextLine[]
      com.sun.javafx.text.TextRun

      There also seems to be a never ending increase of "PseudoClassStates" that never get released, we noticed this across the board in any JFX control. Perhaps CSS plays a part.

      I'll attach a screenshot of my debugger view after posting the initial bug into Jira.

      Test Code:
      ---

      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.concurrent.Task;
      import javafx.geometry.Insets;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.Label;
      import javafx.scene.layout.VBox;
      import javafx.stage.Stage;

      public class TextMemoryLeak extends Application {

      private static final String _StrHello = "Hello ";

      private static int _iterations;

      private static Label _target;

      private static Task<Void> _everySecond;

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

      @Override
      public void start(Stage primaryStage) throws Exception {
      VBox content = new VBox(10);

      _target = new Label("Testing");

      Button start = new Button("Start");
      start.setOnAction(e -> {
      start();
      });

      Button stop = new Button("Stop");
      stop.setOnAction(e -> {
      _everySecond.cancel();
      });

      content.setPadding(new Insets(20));
      content.getChildren().addAll(_target, start, stop);
      Scene scene = new Scene(content, 600, 500);
      primaryStage.setTitle("Text Memory Leak");
      primaryStage.setScene(scene);
      primaryStage.show();
      }

      private void start() {
      _everySecond = new Task<Void>() {

      @Override
      protected Void call() throws Exception {
      while (true) {
      Thread.sleep(10);
      Platform.runLater(() -> {
      _target.setText(String.format("%s %s", _StrHello, _iterations));
      _iterations++;
      });
      if (isCancelled()) {
      return null;
      }
      }
      }

      };
      new Thread(_everySecond).start();
      }
      }


            vadim Vadim Pakhnushev
            ecrumhornjfx Emil Crumhorn (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: