Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8161664

Memory leak in com.apple.laf.AquaProgressBarUI: removed progress bar still referenced

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 8u92
    • Fix Version/s: 9
    • Component/s: client-libs
    • Labels:
      None
    • Subcomponent:
    • Resolved In Build:
      b133
    • CPU:
      x86
    • OS:
      other

      Backports

        Description

        FULL PRODUCT VERSION:
        java version "1.8.0_91"
        Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
        Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Darwin saotome-57590.local 15.4.0 Darwin Kernel Version 15.4.0: Fri Feb 26 22:08:05 PST 2016; root:xnu-3248.40.184~3/RELEASE_X86_64 x86_64

        A DESCRIPTION OF THE PROBLEM :
        In certain scenarios, the Timer in the Animator class of the AquaProgressBarUI remains running, even when the JProgressBar is already removed from the Swing hierarchy.
        This running Timer avoids that the JProgressBar can be GC-ed.

        The problem can be reproduced with the following program

        import java.awt.EventQueue;
        import java.lang.ref.WeakReference;
        import java.lang.reflect.InvocationTargetException;

        import javax.swing.JFrame;
        import javax.swing.JPanel;
        import javax.swing.JProgressBar;

        public class AquaProgressBarUIMemoryLeakTest {

          private static JFrame sFrame;
          private static WeakReference<JProgressBar> sProgressBar;

          public static void main(String[] args) throws InvocationTargetException, InterruptedException {
            EventQueue.invokeAndWait(new Runnable() {
              @Override
              public void run() {
                showUI();
              }
            });
            //Allow the UI to be painted before disposing
            EventQueue.invokeAndWait(new Runnable() {
              @Override
              public void run() {
                disposeUI();
              }
            });

            System.runFinalization();
            System.gc();
            JProgressBar progressBar = sProgressBar.get();
            if ( progressBar != null ){
              throw new RuntimeException("Progress bar should have been GC-ed");
            }
          }

          private static void showUI(){
            sFrame = new JFrame();

            JProgressBar progressBar = new JProgressBar();
            progressBar.setVisible(false);
            progressBar.setIndeterminate(false);
            progressBar.setIndeterminate(true);
            progressBar.setIndeterminate(false);
            progressBar.setValue(10);
            progressBar.setString("Progress");

            sFrame.add(progressBar);

            sProgressBar = new WeakReference<>(progressBar);

            sFrame.setSize(200,200);
            sFrame.setVisible(true);
          }

          private static void disposeUI(){
            sFrame.setContentPane(new JPanel());
            sFrame.dispose();
            sFrame = null;
          }
        }

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  rstevens Robin Stevens
                  Reporter:
                  rstevens Robin Stevens
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: