JDK-6368950 : Memory leak when closing a Frame with icon set
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0u6
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_10
  • CPU: sparc
  • Submitted: 2006-01-04
  • Updated: 2011-01-19
  • Resolved: 2006-01-10
Related Reports
Duplicate :  
Relates :  
Description
The following test case, which was taken from the JDC comments for bug
  6257260: Memory leak on closing JFrame
shows a memory leak in XAWT in 5.0:

---- test begins -----
import java.awt.Button;
import java.awt.Event;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class XtoolkitIconLeak extends Frame {

    static boolean S_allowIcon = true;

    static int S_offset = 100;
    boolean S_etype = true;
    Button S_b = null;
    byte[] S_bigDummyData = null;

    public XtoolkitIconLeak(String name, boolean etype /* if true then exit app on windowClose() */){
        S_etype = etype;
        setTitle(name);
        /*--------------------------------------------------------------
         * Under Solaris 10 X86 if we intall an ICON in the frame, GC fails
         * and we leak 5M per window iteration (e.g. new frame and close)
         *   -Dawt.toolkit=sun.awt.X11.XToolkit
         * or
         *   unsetenv AWT_TOOLKIT
         */
        Toolkit kit = Toolkit.getDefaultToolkit();
        Image icon = kit.getImage("1.gif");
        if (S_allowIcon) {
            setIconImage(icon);
        }
        /*--------------------------------------------------------------------*/
        if (S_etype == true) {
            // only the primary window has a new frame button
            setBounds(0,0,250,100);
            setLayout(new GridLayout(1,1));
            S_b = new Button("create new frame");
            add(S_b);
        }
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we){
                dispose();
                doGC(4,"Frame.dispose()");
                if (S_etype == true) {
                    // only the primary window invokes an application exits
                    System.exit(0);
                }
            }
        });
        setVisible(true);
    }

    public void doGC(int passes, String activity)
    {

        Runtime rt = Runtime.getRuntime();
        for (int i = 0; i< passes; i++) {
            System.gc();
            rt.gc();
            rt.runFinalization();
        }
        long free   = rt.freeMemory();
        long total  = rt.totalMemory();
        long used   = total - free;
        String sused = "" + used;
        while (sused.length() < 9) sused = " " + sused ;
        System.out.println("HEAP USED = " + sused + ", ACTIVITY = "  + activity);
    }

    public boolean action(Event event, Object arg)
    {
        if (event.target.equals(S_b)) {
            doGC(4,"new Frame()");
            XtoolkitIconLeak popup = new XtoolkitIconLeak("new sub frame",false);
            S_offset = S_offset + 22;
            popup.setBounds(S_offset, S_offset, 250,100);
            popup.S_bigDummyData = new byte[1000*1000*5];
        }
        return true;
    }

    public static void main(String args[]){
        System.out.println("awt.toolkit="+System.getProperty("awt.toolkit"));
        if (args.length > 0 && args[0].equalsIgnoreCase("NOICON")) {
            XtoolkitIconLeak.S_allowIcon = false;
            System.out.println("Not installing icons on frame via Frame.setIconImage()");
        }
        XtoolkitIconLeak Xtest = new XtoolkitIconLeak("main frame",true);
    }
}
----- test ends -----

I can reproduce the leak on Solaris 10 with Xawt toolkit.
The bug is not reproducible on mustang.

Comments
EVALUATION Couldn't find any differences between testcases for 6368950 (this CR) and 6317336 (fixed in 6.0b53, 6364875 - request to backport)
10-01-2006

EVALUATION Here's at least one reference to the frame which keeps it from being collected: Static reference from sun.awt.X11.XToolkit.winMap (from class sun.awt.X11.XToolkit) : --> java.util.TreeMap@0xf13d87a0 (36 bytes) (field root:) --> java.util.TreeMap$Entry@0xf13de770 (29 bytes) (field right:) --> java.util.TreeMap$Entry@0xf1d6be28 (29 bytes) (field value:) --> sun.awt.X11.XIconWindow@0xf1d6c168 (88 bytes) (field parent:) --> sun.awt.X11.XFramePeer@0xf1d6beb0 (231 bytes) (field target:) --> XtoolkitIconLeak@0xf1d6bcc8 (342 bytes) You can easily create a heap dump with jmap and examine it with jhap from the latest mustang build 1. start the test, create and dispose of a bunch of frames 2. 1.5.0_06/latest/binaries/solaris-sparc/bin/jmap -heap:format=b <pid> 3. jdk1.6.0/solaris-sparc/bin/jhat heap.bin
04-01-2006