JDK-8274023 : Memory Leak in ControlAcceleratorSupport (JFX 17)
  • Type: Bug
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: openjfx17,openjfx18
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2021-09-10
  • Updated: 2022-01-03
  • Resolved: 2021-09-20
Related Reports
Duplicate :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
windows 10
openjdk 16.0.2
jfx17

A DESCRIPTION OF THE PROBLEM :
After updating to jfx 17, I detected memory leak in my application (every controller that has menu items won't get garbage collected after closing its stage), with visualvm I found it was caused by class ControlAcceleratorSupport. This kind of memory leak doesn't happen on jfx 16, so I guess there is something wrong with PR https://github.com/openjdk/jfx/pull/429.

REGRESSION : Last worked in version 16.0.2

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run this sample with jfx 17:
-------------------------------------------------------------------------------------
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;

public class App extends Application {

    private static final ArrayList<WeakReference<MenuItem>> uncollectedMenuItems = new ArrayList<>();

    private static void clearNullMenuItems() {
        uncollectedMenuItems.removeIf(ref -> ref.get() == null);
    }

    private static void launchNewStage(Stage stage) {
        MenuItem menuItem = new MenuItem("Restart Stage");
        menuItem.setOnAction(actionEvent -> {
            launchNewStage(new Stage());
            stage.close();
        });
        uncollectedMenuItems.add(new WeakReference<>(menuItem));
        MenuBar menuBar = new MenuBar(new Menu("MENU", null, menuItem));
        Button button = new Button("Call GC and Print MenuItems");
        button.setOnAction(actionEvent -> {
            System.gc();
            clearNullMenuItems();
            System.out.println(Arrays.toString(uncollectedMenuItems.toArray()));
        });
        StackPane root = new StackPane(menuBar, button);
        StackPane.setAlignment(menuBar, Pos.TOP_CENTER);
        stage.setTitle("JFX-Test");
        stage.setMinWidth(400.0);
        stage.setMinHeight(300.0);
        stage.setScene(new Scene(root));
        stage.show();
    }

    @Override
    public void start(Stage primaryStage) {
        launchNewStage(primaryStage);
    }

    public static void main(String[] args) {
        launch();
    }
}
-------------------------------------------------------------------------------------
Click "MENU"-> "Restart Stage" several times, then click the button "Call GC and Print MenuItems".

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Only see one item printed to console.
ACTUAL -
Multiple items were printed to console.

FREQUENCY : always



Comments
Duplicate submission JDK-8274022 from the same submitter
20-09-2021