JavaFX: TouchGesture Memory Leak?
In one of my projects I was fighting with a memory leak the last couple of days (yes … “couple”) and I came to the conclusion that there might be an issue related to touch / scroll gestures. In the sample below I have two buttons. The first one creates a list view with one thousand rows, the second one removes it.
I made the following observations:
- when I click on “create” and immediately on “destroy” then everything will be garbage collected.
- when I click on “create” and use the scrollbar to scroll down and then click on “destroy” everything will be garbage collected.
- when I click on “create” and then use a gesture to scroll down (with my Mac Magic Mouse) then the garbage collection fails.
I have used jvisualvm that ships with the JDK and I use the “Sampler” tab to look at the heap space. I filter for the “TestItem” class and I can see that always those items are still in memory that were created for the last ListView after pressing the “create” button.
When I dump the heap and analyze it with the “Eclipse Memory Analyzer” I can see that it is most likely the ScrollGesture that keeps a reference to the list view / the data.
Can anyone confirm this? Is this a known bug? I could not find anything related to this issue in the Java bug database.
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 listView = new ListView(); List 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); } }
Reference: | JavaFX: TouchGesture Memory Leak? from our JCG partner Dirk Lemmermann at the Pixel Perfect blog. |