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

Alexander Scherbatiy alexandr.scherbatiy at oracle.com
Fri Jan 31 15:47:10 UTC 2014


   Hello Nick,

   Could you create an issue on it http://bugreport.java.com/bugreport ?

  Thanks,
  Alexandr.

On 1/30/2014 9:55 PM, Nick Miyake wrote:
> 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




More information about the swing-dev mailing list