JDK-8274022 : Additional Memory Leak in ControlAcceleratorSupport
  • Type: Bug
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: 8u321,openjfx17,openjfx18
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2021-09-17
  • Updated: 2022-03-21
  • Resolved: 2021-11-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 Other
8u331Fixed openjfx17.0.2Fixed
Related Reports
Blocks :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Windows 10 1909 64bit
OpenJDK 17 (build 17+35-2724)

A DESCRIPTION OF THE PROBLEM :
If there are MenuItems in the Stage, after closing the Stage, the MenuItems won't get garbage collected, and thus also leaking its listeners and other related objects. It only happens on JFX 17, on JFX 16 the memory leak won't happen. Might be related with https://github.com/openjdk/jfx/pull/429.

REGRESSION : Last worked in version openjfx16

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Place a MenuItem in a Stage and launch this Stage, then launch a new Stage and close previous Stage, the MenuItem in the previous Stage won't get garbage collected.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The MenuItem in the closed Stage get garbage collected.
ACTUAL -
The MenuItem in the closed Stage won't be garbage collected.

---------- BEGIN SOURCE ----------
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 JavaApp 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();
    }
}
---------- END SOURCE ----------

FREQUENCY : always



Comments
Changeset: 0d5b8f8b Author: Florian Kirmaier <fkirmaier@openjdk.org> Committer: Kevin Rushforth <kcr@openjdk.org> Date: 2021-11-15 16:28:40 +0000 URL: https://git.openjdk.java.net/jfx/commit/0d5b8f8b3f71b1301a65adcc41fe0c7308d4ff01
15-11-2021

Based on the comments in the PR about how frequently this is encountered, the fact that there is no known application level workaround, and given that it is a regression introduced in JavaFX 17, I am raising the priority to P2. This would be a good candidate for a backport to a JavaFX 17 update release.
30-10-2021

I've seen it quite often since the latest version - so this is probably quite common.
16-10-2021

I have the issue with MenuButtons whereas the issue here is raised on MenuBar. Calling "dispose()" on the MenuButtonSkin seems to be working but I have not tested it specifically on MenuBar.
08-10-2021

hmm .. dispose the skin of which control when? don't see a menuButton, *cough, could you update the example, please.
08-10-2021

Do we have a work-around that can be manually applied somehow to remove the leak? Edit: it seems that calling "dispose()" on the skin manually when the menuButton is not used anymore is working to remove the memory leak.
06-10-2021

Checked with attached testcase in Windows 10, Issue is reproducible<attached screenshot for reference> and is regression from openjfx17 Test Result: ========= 8u301: Pass openjfx11: Pass openjfx16: Pass openjfx17: Fail <--Regression openjfx18: Fail
20-09-2021

It's possible that the fix for JDK-8208088 fixed one memory leak, while introducing another.
20-09-2021