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

ControlAcceleratorSupport menu items listener causes memory leak

    XMLWordPrintable

Details

    • b24
    • generic
    • generic

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Microsoft Windows [Version 10.0.17134.1040]
      openjdk version "13" 2019-09-17
      OpenJDK Runtime Environment AdoptOpenJDK (build 13+33)
      OpenJDK 64-Bit Server VM AdoptOpenJDK (build 13+33, mixed mode, sharing)


      A DESCRIPTION OF THE PROBLEM :
      ControlAcceleratorSupport menu items listener is not cleared in removeAcceleratorsFromScene action, which causes memory leak while moving MenuBar with items to other scene. Removing is called in javafx.scene.control.skin.MenuButtonSkinBase#sceneChangeListener, but it does not handle the items' listener, so it just constantly adds new listeners on scene change, which grow up in memory.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Open provided TwoStagesMenuBarLeakSample.
      2. Keep pressing F11.
      3. Observe the ControlAcceleratorSupport count in memory analyzing tools - jvisualvm or Eclipse MAT.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      After 3. the ControlAcceleratorSupport count should be moreless the same as after 1.
      ACTUAL -
      lambda from ControlAcceleratorSupport count keeps growing up in the memory causing memory leak

      ---------- BEGIN SOURCE ----------

      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.control.Label;
      import javafx.scene.control.Menu;
      import javafx.scene.control.MenuBar;
      import javafx.scene.control.MenuItem;
      import javafx.scene.input.KeyCombination;
      import javafx.scene.input.KeyEvent;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.VBox;
      import javafx.stage.Stage;
      import javafx.stage.StageStyle;

      public class TwoStagesMenuBarLeakSample
      {

          public static void main( String[] args )
          {
              System.err.println( Runtime.version().toString() );
              Application.launch( TwoStagesMenuBarLeakSample.MainFx.class, args );
          }

          public static class MainFx extends Application
          {

              @Override
              public void start( final Stage primaryStage ) throws Exception
              {
                  final BorderPane borderPane = new BorderPane( new VBox( new Label( "sample" ) ) );
                  final Menu one = new Menu( "_One" );
                  one.getItems().add( new MenuItem( "Sample 1" ) );
                  one.getItems().add( new MenuItem( "Sample 2" ) );
                  one.getItems().add( new MenuItem( "Sample 3" ) );
                  one.getItems().add( new MenuItem( "Sample 4" ) );
                  final var menuBar = new MenuBar( one );
                  borderPane.setTop( menuBar );
                  borderPane.setCenter( new Label( "Press F11 to switch MenuBar to other window." ) );
                  Scene scene = new Scene( borderPane, 800, 600 );
                  primaryStage.setScene( scene );
                  primaryStage.show();
                  final var stage2 = new Stage( StageStyle.DECORATED );
                  final BorderPane stage2Container = new BorderPane();
                  stage2Container.setCenter( new Label( "Press F11 to switch MenuBar to other window." ) );
                  stage2.setScene( new Scene( stage2Container, 800, 600 ) );
                  primaryStage.addEventHandler( KeyEvent.KEY_PRESSED, aKeyEvent -> {
                      if( KeyCombination.keyCombination( "F11" ).match( aKeyEvent ) )
                      {
                          stage2Container.setTop( menuBar );
                          stage2.requestFocus();
                      }
                  } );
                  stage2.addEventHandler( KeyEvent.KEY_PRESSED, aKeyEvent -> {
                      if( KeyCombination.keyCombination( "F11" ).match( aKeyEvent ) )
                      {
                          borderPane.setTop( menuBar );
                          primaryStage.requestFocus();
                      }
                  } );
                  stage2.show();
              }

          }

      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Recreating menu bar on scene change.

      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              arapte Ambarish Rapte
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: