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

JInternalFrame Not Being Finalized After Closing

XMLWordPrintable

    • b28
    • generic, x86
    • generic, windows_xp
    • Not verified

      Name: jk109818 Date: 10/07/2002


      FULL PRODUCT VERSION :
      java version "1.4.0_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
      Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)

      and

      java version "1.4.1"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
      Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)

      FULL OPERATING SYSTEM VERSION :
      Windows XP, Service Pack 1

      A DESCRIPTION OF THE PROBLEM :
      Related to Bug ID 4748141.

      If a single JInternalFrame is added to a JDesktopPane and
      then closed, the instance is not available for garbage
      collection UNTIL a new JInternalFrame is added to the
      desktop. It seems like even though the JInternalFrame has
      been "disposed", a reference is still maintained to the
      JInternalFrame as the selected window. When the new
      JInternalFrame is added, the reference is shifted allowing
      the "disposed" JInternalFrame to be garbage collected.

      In essence, this is a memory leak.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the code as shown in the Source Code section. Click
      the "Add Frame" button, close the initial frame, and click
      the "Garbage Collect" button (sets the state to what is
      described in bug ID 4748141). Click the "Add Frame"
      button, close the new frame, and click the "Garbage
      Collect" button. Note in the output window that the
      println() statement in the finalize() method of the custom
      JInternalFrame class does not trigger. Now click the "Add
      Frame" button followed by the "Garbage Collect" button.
      You will see the println() statement in the finalize()
      method of the original custom JInternalFrame() instance
      trigger.
      NOW, the original JInternalFrame is allowed to garbage
      collect.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Should expect to see the finalize() method for the
      JInternalFrame class to trigger after it has been disposed
      of and the garbage collector fires.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.*;
      import javax.swing.event.*;

      public class InternalFrameTest
      {
          public static void main(String[] args)
          {
              JFrame frame = new JFrame("Internal Frame Test");
              frame.getContentPane().setLayout(new BorderLayout());
              final JDesktopPane desktopPane = new JDesktopPane();
              desktopPane.setDesktopManager(new DefaultDesktopManager());
              frame.getContentPane().add(desktopPane, BorderLayout.CENTER);
              
              InternalFrameListener iFrameListener = new InternalFrameAdapter() {
                  public void internalFrameClosed(InternalFrameEvent evt)
                  {
                      System.out.println("Number of Frames Remaining=" +
      desktopPane.getAllFrames().length);
                  }
              };
              
      // for (int i = 0; i < 10; i++) {
      // JInternalFrame iFrame = new CustomInternalFrame("Frame " + i);
      // iFrame.setSize(200, 200);
      // iFrame.addInternalFrameListener(iFrameListener);
      // desktopPane.add(iFrame);
      // iFrame.setVisible(true);
      // }
             
              JButton button = new JButton("Add Frame");
              button.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent evt)
                  {
                      System.out.println("Adding new internal frame!");
                      CustomInternalFrame iFrame = new CustomInternalFrame("Dummy
      Frame");
                      iFrame.setSize(200, 200);
                      desktopPane.add(iFrame);
                      iFrame.setVisible(true);
                  }
              });
              frame.getContentPane().add(button, BorderLayout.NORTH);
              
              button = new JButton("Garbage Collect");
              button.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent evt)
                  {
                      System.out.println("Firing garbage collection!");
                      System.gc();
                  }
              });
              frame.getContentPane().add(button, BorderLayout.SOUTH);
              
              frame.setSize(800, 600);
              frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
              frame.setVisible(true);
              System.runFinalizersOnExit(true);
          }
          
          
          public static class CustomInternalFrame extends JInternalFrame
          {
              private static int iFrameIdCounter = 0;
              
              private int iFrameId;
              
              public CustomInternalFrame(String title)
              {
                  super(title, true, true, true, true);
                  iFrameId = iFrameIdCounter++;
              }
              
              protected void finalize()
              {
                  System.out.println("Discarding frame " + iFrameId);
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      None Identified
      (Review ID: 165240)
      ======================================================================

            mcherkas Mikhail Cherkasov (Inactive)
            jkimsunw Jeffrey Kim (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: