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