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

[macosx]Adding 22k JMenuItems to a JMenu tree terminating in a JMenuBar freezes the UI

    XMLWordPrintable

Details

    Description

      ADDITIONAL SYSTEM INFORMATION :
      OS Build number: macOS 12.6.1 (21G217)
      Memory Usage: 522 MB / 4096 MB (195 MB allocated, but free)
      Java version: 17.0.5+8, Eclipse Adoptium, OpenJDK 64-Bit Server VM (also verified on Java 19 with attached source)
      Look and Feel: com.apple.laf.AquaLookAndFeel
      Screen: Display 188945233 1920×1080 (scaling 1.00×1.00) Display 188945231 1920×1080 (scaling 1.00×1.00) Display 69733382 1680×1050 (scaling 2.00×2.00)
      Maximum Screen Size: 1920×1080

      A DESCRIPTION OF THE PROBLEM :
      Please add label "josm-found" to this bug report.

      This requires the application to be using the screen menu bar (`apple.laf.useScreenMenuBar`).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Start JOSM ( available at https://josm.openstreetmap.de/josm-tested.jar )
      2. Open JOSM Preferences (`JOSM` -> `Preferences`)
      3. Go to `Tagging Presets` (looks like a tag, should be third from the bottom of the tabbed list)
      4. Search for `Name Suggestion Index` and enable it (blue right arrow)
      5. Press `OK`
      6. Wait a second for preferences to close
      7. Click on `Presets` in the main menu bar.
      8. Come back in 20 minutes, once processing is finished

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      <5s pause (Metal LaF on a Raspberry Pi 4)
      ACTUAL -
      ~20 minutes of an application UI freeze.
      From profiling (async profiler), 94%+ of the time spent during this freeze was in `com.apple.laf.ScreenMenu.invokeOpenLater()`.

      ---- Stack trace from profiler (94.21% of all) ----
      __CFRunLoopRun
      CFRunLoopRunSpecific
      -[NSRunLoop(NSRunLoop) runMode:beforeDate:]
      Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoopImpl
      sun.lwawt.macosx.LWCToolkit.doAWTRunLoopImpl(long, boolean, boolean)
      sun.lwawt.macosx.LWCToolkit.doAWTRunLoop(long, boolean)
      sun.lwawt.macosx.LWCToolkit.invokeAndWait(Runnable, Component)
      com.apple.laf.ScreenMenu.invokeOpenLater()

      ---------- BEGIN SOURCE ----------
      import java.awt.event.ActionEvent;

      import javax.swing.AbstractAction;
      import javax.swing.JButton;
      import javax.swing.JFrame;
      import javax.swing.JMenu;
      import javax.swing.JMenuBar;
      import javax.swing.JMenuItem;

      class Scratch {
          public static void main(String[] args) {
              // Set this to different values to see the difference
              int jMenuItemsToMake = 20_000;
              // Set this to true/false to see the difference. `true` is needed to see the bug.
              System.setProperty("apple.laf.useScreenMenuBar", "true");
              System.setProperty("apple.awt.application.name", "Test");
              JFrame frame = new JFrame("test");
              JMenuBar menuBar = new JMenuBar();
              JButton exit = new JButton(new AbstractAction() {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      System.exit(0);
                  }
              });
              exit.setText("Exit");
              menuBar.add(exit);
              frame.setJMenuBar(menuBar);
              frame.setVisible(true);
              JMenu mainMenu = new JMenu("Test many items");
              menuBar.add(mainMenu);
              for (int i = 0; i < jMenuItemsToMake; i++) {
                  mainMenu.add(new JMenuItem("Test " + i));
              }
          }
      }
      ---------- END SOURCE ----------

      FREQUENCY : always


      Attachments

        Activity

          People

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated: