JDK-6386583 : Using JPopupMenu.add(Action) gives a memory leak
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P5
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-02-16
  • Updated: 2011-02-16
  • Resolved: 2006-02-21
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
Sample program doesn't release memory.
The bug is similar to bug ID 4193196 except that the fix was not ported to  JPopupMenu
See http://weblogs.java.net/blog/timboudreau/archive/2005/04/writing_memory.html for details.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class MyFrame extends javax.swing.JFrame {
    MenuAction menuAction = new MenuAction();
    public MyFrame() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBounds (20, 20, 300, 300);
        getContentPane().addMouseListener (new MouseAdapter() {
            public void mouseReleased (MouseEvent me) {
                getPopupMenu().show((Component) me.getSource(), me.getX(), me.getY());
            }
        });
    }
    
    JPopupMenu getPopupMenu() {
        JPopupMenu menu = new JPopupMenu();
        menu.add (new JMenuItem (menuAction));
        return menu;
    }
    
    static final class MenuAction extends AbstractAction {
        public MenuAction() {
            putValue (Action.NAME, "Do Something");
        }
        public void actionPerformed (ActionEvent ae) {
            System.out.println("Action performed");
        }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
One possible workaround removes the memory leak but removes some functionality.
Extend JPopupMenu and override JPopupMenu.createActionComponent:
    protected JMenuItem createActionComponent(Action a) {
        JMenuItem mi = new JMenuItem((String)a.getValue(Action.NAME),
                                     (Icon)a.getValue(Action.SMALL_ICON));
        mi.setHorizontalTextPosition(JButton.TRAILING);
        mi.setVerticalTextPosition(JButton.CENTER);
        mi.setEnabled(a.isEnabled());
	return mi;
    }

Comments
EVALUATION This was fixed as part of the Action cleanup bug 4626632. JPopupMenu was previously creating a non-static inner class to listen for changes, this is problematic because it pinned down the JPopupMenu. With the rewrite the class is non needed and no leak occurs:)
21-02-2006

EVALUATION problem with Actions -> reassigned to the expert
17-02-2006