ADDITIONAL SYSTEM INFORMATION :
OS: Ubuntu 20.04.6 LTS
Java: openjdk version "24.0.2" 2025-07-15
A DESCRIPTION OF THE PROBLEM :
When a Tab containing a graphic node is removed from a TabPane the graphic node is not released even after the original TabPane is detached from the scene. As a result, the original TabPane, its skin remain reachable and cannot be collected by the garbage collector. This leads to a memory leak whenever tabs with graphics are removed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the provided code and press the “Test” button. After that, run the profiler. You will see results similar to this: <LINK>
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
After pressing the "Test" button, all TabPanes should be eligible for garbage collection.
ACTUAL -
After pressing the "Test" button, all TabPanes are not eligible for garbage collection. If you comment line X then everything works as expected.
---------- BEGIN SOURCE ----------
public class Test1 extends Application {
private final List<Tab> tabs = new ArrayList<>();
@Override
public void start(Stage stage) {
VBox root = new VBox();
var button = new Button("Test");
button.setOnAction(e -> {
for (var tab : tabs) {
var tabPane = tab.getTabPane();
tabPane.getTabs().clear();
root.getChildren().remove(tabPane);
}
});
root.getChildren().add(button);
for (var i = 0; i < 10; i++) {
var tab = new Tab("Tab: " + i);
tab.setGraphic(new HBox(new Label("#"))); // LINE X
tabs.add(tab);
var tabPane = new TabPane(tab);
root.getChildren().add(tabPane);
}
Scene scene = new Scene(root, 400, 600);
stage.setScene(scene);
stage.setTitle("StackPane Size Test");
stage.show();
}
public static void main(String[] args) {
launch();
}
}
---------- END SOURCE ----------
OS: Ubuntu 20.04.6 LTS
Java: openjdk version "24.0.2" 2025-07-15
A DESCRIPTION OF THE PROBLEM :
When a Tab containing a graphic node is removed from a TabPane the graphic node is not released even after the original TabPane is detached from the scene. As a result, the original TabPane, its skin remain reachable and cannot be collected by the garbage collector. This leads to a memory leak whenever tabs with graphics are removed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the provided code and press the “Test” button. After that, run the profiler. You will see results similar to this: <LINK>
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
After pressing the "Test" button, all TabPanes should be eligible for garbage collection.
ACTUAL -
After pressing the "Test" button, all TabPanes are not eligible for garbage collection. If you comment line X then everything works as expected.
---------- BEGIN SOURCE ----------
public class Test1 extends Application {
private final List<Tab> tabs = new ArrayList<>();
@Override
public void start(Stage stage) {
VBox root = new VBox();
var button = new Button("Test");
button.setOnAction(e -> {
for (var tab : tabs) {
var tabPane = tab.getTabPane();
tabPane.getTabs().clear();
root.getChildren().remove(tabPane);
}
});
root.getChildren().add(button);
for (var i = 0; i < 10; i++) {
var tab = new Tab("Tab: " + i);
tab.setGraphic(new HBox(new Label("#"))); // LINE X
tabs.add(tab);
var tabPane = new TabPane(tab);
root.getChildren().add(tabPane);
}
Scene scene = new Scene(root, 400, 600);
stage.setScene(scene);
stage.setTitle("StackPane Size Test");
stage.show();
}
public static void main(String[] args) {
launch();
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8283449 TabPane/Tab memory leak
-
- Open
-