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

Memory leak caused by scroll gesture

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 9
    • 8, 9
    • javafx

      FULL PRODUCT VERSION :
      java version "1.8.0_65"
      Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
      Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      MacOS X El Capitan 10.11.1

      A DESCRIPTION OF THE PROBLEM :
      The class "Scene" has a field called scrollGesture which keeps a reference to the last target / node that was scrolled. If the target / node gets removed from the scene then it can not be garbage collected.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      - Create a list view with a list of items (e.g. "TestItem").
      - Add the view to the scene.
      - Scroll the view with a gesture (e.g. swipe down on Mac Magic Mouse)
      - Remove the list view from the scene

      When using jvisualvm you will see that the last list of TestItems will still be in memory / in the heap.

      More details and screenshots on my blog at https://dlemmermann.wordpress.com/2016/01/29/javafx-scrollgesture-memory-leak/


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      All instances of TestItem should have been garbage collected.
      ACTUAL -
      All instances of TestItem are still there.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      No error log, this needs to be profiled. The heap has to be examined.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.ArrayList;
      import java.util.List;

      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.ListView;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.HBox;
      import javafx.stage.Stage;

      public class MemoryLeakListViewApp extends Application {

          @Override
          public void start(Stage primaryStage) throws Exception {
              BorderPane pane = new BorderPane();
              Scene scene = new Scene(pane);

              Button createButton = new Button("Create");
              createButton.setOnAction(evt -> {

                  ListView<TestItem> listView = new ListView<>();

                  List<TestItem> children = new ArrayList<>();
                  for (int i = 0; i < 1000; i++) {
                      children.add(new TestItem("Row " + i));
                  }

                  listView.getItems().setAll(children);
                  pane.setCenter(listView);
              });

              Button deleteButton = new Button("Destroy");
              deleteButton.setOnAction(evt -> {
                  pane.setCenter(null);
              });

              HBox box = new HBox();
              box.getChildren().addAll(createButton, deleteButton);
              pane.setTop(box);

              primaryStage.setScene(scene);
              primaryStage.setWidth(800);
              primaryStage.setHeight(800);
              primaryStage.show();
          }

          static class TestItem {

              private String name;

              public TestItem(String name) {
                  this.name = name;
              }

              @Override
              public String toString() {
                  return name;
              }
          }

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

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      None that I can think of right now.

            ckyang Chien Yang (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: