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

[Text] Memory leak in JavaFX text drawing

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Won't Fix
    • Affects Version/s: 8u40, 9
    • Fix Version/s: 9
    • Component/s: javafx
    • Labels:
    • Environment:

      Windows x64

      Description

      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();
      }
      }


        Attachments

          Activity

            People

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

              Dates

              • Created:
                Updated:
                Resolved:
                Imported: