JDK-4196661 : JDialogs not being garbage collected
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.1.6,1.2.0
  • Priority: P1
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_2.6,windows_nt
  • CPU: generic,x86,sparc
  • Submitted: 1998-12-10
  • Updated: 2013-11-01
  • Resolved: 1999-03-06
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description

Name: krT82822			Date: 12/10/98


Attached is a small program that allows you to bring up an AWT based or
Swing based modal dialog from a menu item. Both of these dialogs
allocate a 5 million byte buffer inside of them. The AWT version can be
shown and dismissed indefinitely, whereas invoking the Swing
version eventually causes a java.lang.OutOfMemoryError.

Analysis with OptimizeIt (a heap analysis/optimizer program) shows that
internal Java/Swing classes retain references to SwingDialog after it is
dismised, therefore it can't be garbage collected. There is no such
problem with AWTDialog.

I am running Windows NT 4.0, SP 3. The problem occurs under JDK
1.1.7/Swing-1.0.3, JDK1.1.7A/Swing-1.0.3, JDK1.2-RC2, and JDK1.2 release, all with standard heap settings.
The problem does *not* occur with JDK1.1.6/Swing-1.0.3.


/**
 * @(#)DialogLeak.java
 * Copyright (c) 1998, David McCullough
 */

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

public class DialogLeak extends JFrame
{
   public DialogLeak()
   {
      super("Dialog Leak Tester");

		JMenuBar  menuBar;
		JMenu     menu;
      JMenuItem menuItem;

      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e)
         {
            System.exit(0);
         }
      });

      menuBar = new JMenuBar();
      menu = new JMenu("Dialog");

      // Display AWT Dialog
      menuItem = menu.add(new AbstractAction("AWT Dialog") {
         public void actionPerformed(ActionEvent e)
         {
            Dialog dlg = new AWTDialog(DialogLeak.this);
            dlg.pack();
            dlg.setVisible(true);
            dlg.dispose();
         }
      });

      // Display Swing Dialog
      menuItem = menu.add(new AbstractAction("Swing Dialog") {
         public void actionPerformed(ActionEvent e)
         {
            // This dialog never gets garbage collected!
            JDialog dlg = new SwingDialog(DialogLeak.this);
            dlg.pack();
            dlg.setVisible(true);
            dlg.dispose();
         }
      });

      // Garbage Collect
      menuItem = menu.add(new AbstractAction("Garbage Collect") {
         public void actionPerformed(ActionEvent e)
         {
            System.gc();
         }
      });

      menuBar.add(menu);
      setJMenuBar(menuBar);
   }

   static public void main(String args[])
   {
      JFrame frame = new DialogLeak();
      frame.setSize(300, 200);
      frame.setVisible(true);
   }
}


class AWTDialog extends Dialog
{
   private byte[] bigBuf;
   public AWTDialog(Frame owner)
   {
      super(owner, "AWT Dialog", true);
      bigBuf = new byte[5000000];

      Button okBtn = new Button("OK");
      okBtn.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e)
         {
            setVisible(false);
         }
      });

      add("Center", okBtn);
   }
}

class SwingDialog extends JDialog
{
   private byte[] bigBuf;
   public SwingDialog(Frame owner)
   {
      super(owner, "Swing Dialog", true);
      bigBuf = new byte[5000000];

      JButton okBtn = new JButton("OK");
      okBtn.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e)
         {
            setVisible(false);
         }
      });

      getContentPane().add("Center", okBtn);
   }
}
(Review ID: 47504)
======================================================================
fariba.alavi@eng 1998-12-17 

This problem is also reported by Novell.  Here is the description of the problem
along with a test case.  You can also see /home/faribaa/novell-dec where I've put the test case along with the dump.hprof file.

The problem is with dialogs not being gc-ed and therefore everything associated with the dialog is not being disposed. We have some complex dialogs that cause our application to run out of memory in a very little time.

We did a little testing and found the following -

jdk1.1.6 does not exhibit the problem.

jdk1.1.7b, jdk1.1.7u, jdk1.18c,  and jdk1.2 all are similar, they do the following -

1. If no JFC is used, just one copy of the dialog is kept around.
2. If an empty JDialog is used, one or two copies of the dialog is kept around.
3. If the JDialog contains JButtons, a copy for every launch is kept around.

Below is a test code (using jdk1.2).   

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

public class DialogTest
{
   static Frame frame = null;

    public static void main(String s[])
    {
        frame = new Frame("Dialog Test");
        Button dlgButton = new Button("Test Dialog");
        dlgButton.addActionListener(
         new ActionListener()
         {
             public void actionPerformed(ActionEvent e)
             {
                 MyDialog dlg = new MyDialog(frame,"The Dialog");
                 dlg.setVisible(true);
             }
         }
        );
        frame.setSize(400,400);
        //frame.getContentPane().setLayout(new FlowLayout());
        //frame.getContentPane().add(dlgButton);
        frame.setLayout(new FlowLayout());
        frame.add(dlgButton);
        frame.setVisible(true);
                  Button b = new Button("Quit");
                  b.addActionListener(new ActionListener()
                  {
                     public void actionPerformed(ActionEvent e)
                          {
                             System.exit(0);
                          }
                  });
                  frame.add(b);
    }
}//class Dialog Test


class MyDialog extends JDialog implements ActionListener
{
    JButton okButton = null;

    public MyDialog(Frame parent, String title)
    {
        super(parent, title, true);    // modal dlg
        okButton = new JButton("OK");
        okButton.addActionListener(this);
       setSize(100,100);
        getContentPane().setLayout(new FlowLayout());
        getContentPane().add(okButton);
        //setLayout(new FlowLayout());
        //add(okButton);
    }

    // ActionListener interface implemenation
    public void actionPerformed(ActionEvent e)
    {
        setVisible(false);
        dispose();
    }

}//class MyDialog


Comments
WORK AROUND Name: krT82822 Date: 12/10/98 Use JDK1.1.6/Swing-1.0.3 ======================================================================
11-06-2004

EVALUATION It looks likely that this is related to bug ID# 4193022, but I'm not a 100% sure, so I won't dup it. steve.wilson@eng 1999-01-06 While a number of leaks were fixed in 1.1.8/1.2.2, there still seems to be something preventing JDialogs from being GC'd. it's not obvious from first running of OptimizeIt; will require more thorough analysis. amy.fowler@Eng 1999-02-16 Verified as duplicate of 4193022. robi.khan@eng 1999-03-05
16-02-1999