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

JInternalFrame selection (toFront) allocs lots of non-gced JMenuItem obs

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.4.0
    • 1.3.0
    • client-libs
    • beta
    • x86
    • windows_nt



      Name: skT45625 Date: 05/25/2000


      1.3.0-C (HotSpot Client VM 1.3.0-C mixed mode)

      We have our Swing app's mem leaks down to near zero (thanks for 1.3's
      improvements!) with the exception of JMenuItem objs (& related objs) discussed
      in this bug submission. It appears that new JMenuItems (for JInternalFrame
      system menu L&Fs) are allocated every time a JInternalFrame is selected. It
      can be a user titlebar click selection, or a programmatic one that setSelected
      (true)s or toFront()s the JIF. Tracing down, it appears that the JIF's system
      menu is rebuilt every time the JIF is selected.

      The good news: Most of the JMenuItem related objs seem reachable (not able to
      be gced) *only* until the JInternalFrame is closed (w/DISPOSE opt.).

      The bad news: If the JIF is not closed, the JMenuItem stuff accumulates until
      an out-of-memory condition occurs (the weak ref argument like that in:
      http://developer.java.sun.com/developer/bugParade/bugs/4280094.html
      does not appear to hold).

      Using your favorite heap analyzer (I used OptimizeIT 3.1), run the hastily
      constructed example code at end (using -Xms3M & -Xmx5M to show refs are not
      released). Use MakeFrame to open a 3-5 JIFs & reset your heap obj counters.
      Now click each of the JIF titlebars successively (or use Start Timer button to
      spawn a Timer to do this) and watch the heap. The new 1.3 client hotspot gc
      thread does a great job of reducing the heap, but ultimately the JMenuItem objs
      will exhaust the heap.

      If you close the JIFs, most of the JMenuItem-related objs will be released.

      Granted, this is not as serious as it could be because most GUIs probably
      result in JIFs being closed/disposed. In certain GUI designs, however, some
      desktop JIFs may remain on the desktop for the entire session.

      Once example is a lightweight/JIF progress monitor that is added to the desktop
      and setVisible/toFronted during threaded/long processes. Its JIF is never
      closed/disposed & every display (toFront) causes this heap condition. Another
      example is our GUI where a row selection in one GUI causes several other JIFs
      to be updated.... a JIF setSelected/toFront cascade cannot be used to inform
      the users of the JIF updates due to this bug.

      Example code (sorry for any cut&paste problems):

      /* Demonstrates Selecting JIFs (causing toFront calls) causes lots of JMenuItem
      related non-gced objects.
         Run with -Xms3M -Xmx6M to reduce heap to show that the objs are not gced &
      an outofmem will occur.
         Shows apparent JMenuItem & related obj leakage under 1.2.X & 1.3.0 FCS for
      L&Fs with System menus
         (mostly as long as JIFs are open... many JMenuItem objs are released upon
      JIF close). */

      import javax.swing.*;
      import javax.swing.event.*;
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.Timer;

      public class JFrame1 extends JFrame {
          JDesktopPane desktop;
          static int frameCount = 1;

          public JFrame1() {
              super("JFrame Internal Frames Demo");
                                
              try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName
      ()); }
              catch (Exception exc) { System.out.println("Error loading L&F: " +
      exc); }
                            
              final JSplitPane splitPane = new JSplitPane
      (JSplitPane.HORIZONTAL_SPLIT);
                          
              final JDesktopPane desktop = new JDesktopPane();
              splitPane.setLeftComponent(new JLabel("Test"));
              splitPane.setRightComponent(desktop);
                              
              final JInternalFrame makeFrame = new JInternalFrame("Frame
      Maker",true,false,true,true);
                                
              final JButton button = new JButton("Make Frame");
              button.addActionListener(new ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent event) {
                      final JInternalFrame internal =
                          new JInternalFrame("Frame #"+
      (frameCount++),true,true,true,true);
                      internal.setDefaultCloseOperation
      (JInternalFrame.DISPOSE_ON_CLOSE);
                      internal.getContentPane().add(new JLabel
      ("Test"),BorderLayout.CENTER);
                      internal.setBounds( frameCount*10 , frameCount*10 , 200, 150);
                      internal.setOpaque(true);
                      internal.setVisible(true);
                      desktop.add(internal);
                      internal.toFront();
      splitPane.repaint();
      }
              });
              makeFrame.getContentPane().add(button,BorderLayout.CENTER);
                          
              // Setup a hasty timer to simulate user JIF selects....
              final Timer warningTimer = new Timer(1500, new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
                      final Component[] comps = desktop.getComponents();
                      SwingUtilities.invokeLater( new Runnable() {
                          public void run() {
                              for (int k = 0; k < comps.length; k++) {
                                  // all comps should be JIFs...
                                  try {
                                      JInternalFrame jif = (JInternalFrame)comps[k];
                                      // Do not select JIF with MakeFrame
                                      if (jif != makeFrame) jif.setSelected(true);
                                  }
      catch (Exception e) {
      System.out.println("setSelected exception
      e:"+e);
      }
                              }
                          }
                      });
      }
              });
              warningTimer.setCoalesce(true);
              warningTimer.setRepeats(true);
                  
              final JButton startTimer = new JButton("Start Timer");
              final JButton stopTimer = new JButton("Stop Timer");
                  
              startTimer.addActionListener(new ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent event) {
      if ( desktop.getComponentCount() > 1) {
      warningTimer.start();
      startTimer.setEnabled(false);
      stopTimer.setEnabled(true);
      }
      else System.out.println("Only 1 JIF exists... Timer thread
      NOT spawned");
      }
              });
              makeFrame.getContentPane().add(startTimer,BorderLayout.NORTH);
                          
              stopTimer.addActionListener(new ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent event) {
      warningTimer.stop();
      startTimer.setEnabled(true);
      stopTimer.setEnabled(false);
      }
              });
              makeFrame.getContentPane().add(stopTimer,BorderLayout.SOUTH);
              
              makeFrame.setVisible(true);
              makeFrame.setBounds(200,0,200,120);
              desktop.add(makeFrame);
              getContentPane().add(splitPane,BorderLayout.CENTER);
              desktop.setSize(500,500);
                                
              getContentPane().validate();
              getContentPane().setVisible(true);
                       
              this.addWindowListener( new WindowAdapter() {
                  public void windowClosing(WindowEvent event) {
                      setVisible(false);
                      dispose();
                      System.exit(0);
                  }
              });
              setSize(750, 560);
              show();
          }
          public static void main(String args[]) {
              new JFrame1();
          }
       }

      icsbug
      (Review ID: 105277)
      ======================================================================

            joutwatesunw Joshua Outwater (Inactive)
            skondamasunw Suresh Kondamareddy (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: