On 7/19/2016 12:27 PM, Robin Stevens wrote:
Hello,
I wanted to discuss my approach for issue JDK-8161664
(https://bugs.openjdk.java.net/browse/JDK-8161664) before I started
working on this issue.
In certain scenarios (see the JIRA issue for an example), the Timer in
the Animator inner class of the AquaProgressBarUI class remains
running, even when the JProgressBar has already been removed from the
UI. This causes a memory leak, as that running Timer avoids that the
JProgressBar can be GC-ed. As long as the Timer is running, the
JProgressBar is referenced through
Timer -> ActionListener (=Animator inner class) -> AquaProgressBarUI
outer class -> JProgressBar field
I see two possible approaches to fix this:
1) I carefully investigate the particular scenario I found, and try to
figure out why the Timer is not stopped and fix this particular
scenario. This offers of course no guarantees that there are no other
scenarios which keep the Timer running.
2) I replace one of the hard references with a weak reference, hence
avoiding the memory leak in all cases.
If I do not attach the Animator inner class directly as listener to
the timer, but use another ActionListener which only has a
WeakReference to the Animator class, the memory leak is solved.
The ActionListener could then stop the timer when the timer is fired
and the WeakReference#get returns null.
I prefer the second approach. By cutting the hard reference between
the Timer and the Animator + stopping the Timer when the Animator is
GC-ed, I ensure that the Timer cannot cause a memory leak anymore.
This avoids overlooking certain scenarios.
Any input on this ? Any preferences for a certain approach, or
proposal for another approach.
Does other L&Fs (for example Metal) have the same memory leak with
the JProgressBar? If no, it would be interesting to know what is the
difference between them and the AquaProgressBarUI.
Thanks,
Alexandr.
Robin