Re: heap memory issue, related with garbage collection
On 11/28/2014 4:29 PM, John wrote:
I solved my problem.
Congratulations! But read on ...
Here is my original code:
private void displayPic(final int picCount)
{
String pngFileNameWithPath = xxx; //get PNG file name based on int picCount
final ImageIcon imageIcon = new ImageIcon(pngFileNameWithPath);
final JLabel picLabel = new JLabel();
picLabel.setIcon(imageIcon);
final JPanel picPanel = new JPanel();
picPanel.add(picLabel);
_jPanel.add(picPanel, BorderLayout.CENTER);
_jFrame.getContentPane().add(_jPanel);
_jFrame.setTitle(pngFileNameWithPath);
_jFrame.setVisible(true);
}
The problem is when this method was called 150 times, then heap memory ran out. I found the cause is that at the end of the method, even though those references('picLabel', 'picLabel' etc) are out of scope and dead, the objects that once were referenced by them were not garbage collected and that was due to that those objects, even though not referenced by 'picLabel', 'picLabel' etc, were still referenced by some other references.
Yes: As Tassilo Horn and I wrote, you added these objects to the
frame (over and over again). The frame, naturally, needs to keep
references to the things it contains, and those references just kept
piling up, "pinning" the objects they referred to.
I added these code near the end of the method:
picLabel.removeAll();
picPanel.removeAll();
_jPanel.remove(picPanel);
_jFrame.getContentPane().remove(_jPanel);
Removing things before adding new ones is a good idea, but what
do you mean by "near the end?" Removing what you've just added is
not only pointless, but counterproductive. You *should* wind up with
nothing showing at all (unless you're still doing things from the
wrong thread, in which case there's no telling what might happen).
I am not sure if they all are needed or if one is covering another. But anyway, I can keep all references inside the method(no need to make them class instance variables) and no more memory issue.
Read Tassilo Horn's response again. All this adding and removing
is *much* more work than is needed; you've built a sort of Rube Goldberg
program, a mechanism far more complex than the job requires. All you
really need to do is
- When you construct the GUI, put a JLabel in a JPanel and put the
JPanel in the JFrame. You never need to remove anything, and you never
need to add anything else except whatever buttons and things you might
require.
- When you want to display a new image, build the ImageIcon just as
you do now, and just call setIcon() on the JLabel.
- Remember to do all these things on the Event Dispatch Thread.
.... and that's it! No adding, removing, or pointless running around.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM