<Swing Dev> Swing memory leak caused by JFrame.setLocation?

Nick Miyake nmiyake at palantir.com
Thu Jan 30 17:55:54 UTC 2014


Hello,

I believe I have found an issue that causes a memory leak in the Java
process when using "JFrame.setLocation".

If you launch the application in the sample program below (which simply
calls "setLocation" on a JFrame repeatedly) in MacOS using JDK 1.7.0_06 or
later and observe the memory usage of the application using Activity Monitor
and click the "setLocation x 1000" button, the memory usage of the program
nearly triples (on my machine, it goes from 50MB to 150MB) and never
decreases after that. The issue seems to be with the Java process itself, as
the heap/memory usage reported by JConsole does not change. Repeating the
same steps using JDK 1.7.0_05 or earlier shows that this leak does not seem
to happen.

Sample code:
----------------------------
public final class MemoryLeakRepro {
private static final int NUM_SET_LOCATIONS = 1000;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
            final JFrame frame = new JFrame("Test");
        JPanel content = new JPanel(new GridLayout(1, 1));

        JButton button = new JButton("setLocation x " + NUM_SET_LOCATIONS);
        content.add(button);
        button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
        for (int i = 0; i < NUM_SET_LOCATIONS; i++) {
        int delta = (i % 2 == 0 ? 1 : -1);
                    frame.setLocation(frame.getX() + delta, frame.getY() +
delta);
        }
        }
        });
        frame.setContentPane(content);
        
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
}
}
----------------------------

A similar issue seems to reproduce on Windows as well (although not using
the same "setLocation" button method). If you use the other sample program
below, increase the window size and then drag the JPanel all over the screen
repeatedly, the memory usage goes from around 28MB to 34MB or so and never
comes back down. Repeating the process can cause it to take up more and more
memory, which never seems to be released. The same behavior is not observed
when dragging the native title bar. This behavior occurs in both JDK
1.6.0_45 and in all versions of JDK 7 I tested.

Sample code:
----------------------------
public final class MemoryLeakRepro {
private static final int NUM_SET_LOCATIONS = 1000;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
            final JFrame frame = new JFrame("Test");
        JPanel content = new JPanel(new GridLayout(1, 1));

        JPanel dragPanel = new JPanel();
        dragPanel.setPreferredSize(new Dimension(100, 100));
        FrameDragger frameDragger = new FrameDragger(frame);
        dragPanel.addMouseListener(frameDragger);
dragPanel.addMouseMotionListener(frameDragger);
        content.add(dragPanel);
        frame.setContentPane(content);
        
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
}
private static final class FrameDragger extends MouseAdapter {
private final JFrame frame;
private int prevMouseX;
private int prevMouseY;
public FrameDragger(JFrame frame) {
this.frame = frame;
}
    @Override
    public void mousePressed(MouseEvent e) {
        prevMouseX = e.getX();
        prevMouseY = e.getY();
    }
@Override
public void mouseDragged(MouseEvent e) {
int currMouseX = e.getX();
            int currMouseY = e.getY();
            int currWindowX = frame.getX();
            int currWindowY = frame.getY();

            int moveX = currMouseX - prevMouseX;
            int moveY = currMouseY - prevMouseY;
            if (moveX == 0 && moveY == 0) return;

            int newFrameX = currWindowX + moveX;
            int newFrameY = currWindowY + moveY;

            frame.setLocation(newFrameX, newFrameY);
}
}
}
----------------------------

Has anyone here seen this issue in the past or have any ideas about what we
could do to fix it?

Thanks,
-Nick


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20140130/d8c8b1e3/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5034 bytes
Desc: not available
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20140130/d8c8b1e3/smime.p7s>


More information about the swing-dev mailing list