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

JComboBox does not release memory

XMLWordPrintable

    • generic, x86
    • generic, windows_2000

      Name: jl125535 Date: 07/02/2004


      FULL PRODUCT VERSION :
      java version "1.5.0-beta3"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta3-b57)
      Java HotSpot(TM) Client VM (build 1.5.0-beta3-b57, mixed mode)

      java version "1.4.2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
      Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows 2000 [Version 5.00.2195]
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      We have noticed that our application appears to leak memory when a large number of JComboBox components are created in a single session. The test case below isolates this behavior.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the test case below:

      java MemoryLeakTest javax.swing.JComboBox

      This will create large numbers of combo box components, then run GC, and display memory usage, and then repeat. Each time it prints the memory used, and change from the previous iteration.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      After the first few iterations, we expected no change in memory used (or small changes that even out over time). When run with other components, memory usage is flat, or bounces up and down in small incremements:

      C:\temp\mem>java MemoryLeakTest javax.swing.JTextField
      Used(0) = 305912
      Used(1) = 280792 (-25120)
      Used(2) = 281376 (584)
      Used(3) = 280792 (-584)
      Used(4) = 281376 (584)
      Used(5) = 280792 (-584)
      Used(6) = 281376 (584)
      Used(7) = 280792 (-584)
      Used(8) = 281376 (584)
      Used(9) = 280792 (-584)
      Used(10) = 281376 (584)
      Used(11) = 280792 (-584)
      Used(12) = 281448 (656)
      Used(13) = 280864 (-584)
      Used(14) = 281448 (584)
      Used(15) = 280864 (-584)
      Used(16) = 281448 (584)
      Used(17) = 280864 (-584)
      Used(18) = 281448 (584)
      Used(19) = 280864 (-584)
      Used(20) = 281448 (584)
      Used(21) = 280864 (-584)
      Used(22) = 281448 (584)
      Used(23) = 280864 (-584)
      Used(24) = 281448 (584)
      Used(25) = 280864 (-584)
      Used(26) = 281448 (584)
      Used(27) = 280864 (-584)
      Used(28) = 281448 (584)
      Used(29) = 280864 (-584)
      Used(30) = 281448 (584)

      C:\temp\mem>java MemoryLeakTest java.util.Vector
      Used(0) = 90424
      Used(1) = 89800 (-624)
      Used(2) = 89800 (0)
      Used(3) = 89800 (0)
      Used(4) = 89800 (0)
      Used(5) = 89800 (0)
      Used(6) = 89800 (0)
      Used(7) = 89800 (0)
      Used(8) = 89800 (0)

      C:\temp\mem>java MemoryLeakTest java.lang.Object
      Used(0) = 90208
      Used(1) = 89800 (-408)
      Used(2) = 89800 (0)
      Used(3) = 89800 (0)
      Used(4) = 89800 (0)
      Used(5) = 89800 (0)
      Used(6) = 89800 (0)
      Used(7) = 89800 (0)
      Used(8) = 89800 (0)
      Used(9) = 89800 (0)
      Used(10) = 89800 (0)
      Used(11) = 89800 (0)
      Used(12) = 89872 (72)
      Used(13) = 89872 (0)
      Used(14) = 89872 (0)
      Used(15) = 89872 (0)
      Used(16) = 89872 (0)

      C:\temp\mem>java MemoryLeakTest javax.swing.JButton
      Used(0) = 220752
      Used(1) = 201624 (-19128)
      Used(2) = 201880 (256)
      Used(3) = 201624 (-256)
      Used(4) = 201880 (256)
      Used(5) = 201624 (-256)
      Used(6) = 201880 (256)
      Used(7) = 201624 (-256)
      Used(8) = 201880 (256)
      Used(9) = 201624 (-256)
      Used(10) = 201880 (256)
      Used(11) = 201624 (-256)
      Used(12) = 201952 (328)
      Used(13) = 201696 (-256)
      Used(14) = 201952 (256)
      Used(15) = 201696 (-256)

      C:\temp\mem>java MemoryLeakTest javax.swing.JDialog
      Used(0) = 701888
      Used(1) = 412976 (-288912)
      Used(2) = 419552 (6576)
      Used(3) = 419552 (0)
      Used(4) = 419552 (0)
      Used(5) = 419552 (0)
      Used(6) = 419552 (0)
      Used(7) = 419552 (0)
      Used(8) = 419552 (0)
      ACTUAL -
      When run with JComboBox, the usage containues to grow (at an average of around 8k per iteration):


      C:\temp\mem>java MemoryLeakTest javax.swing.JComboBox
      Used(0) = 397040
      Used(1) = 362720 (-34320)
      Used(2) = 412400 (49680)
      Used(3) = 422168 (9768)
      Used(4) = 389080 (-33088)
      Used(5) = 393960 (4880)
      Used(6) = 449504 (55544)
      Used(7) = 404304 (-45200)
      Used(8) = 394208 (-10096)
      Used(9) = 404352 (10144)
      Used(10) = 412352 (8000)
      Used(11) = 417552 (5200)
      Used(12) = 424256 (6704)
      Used(13) = 433936 (9680)
      Used(14) = 442264 (8328)
      Used(15) = 450264 (8000)
      Used(16) = 493408 (43144)
      Used(17) = 466232 (-27176)
      Used(18) = 474984 (8752)
      Used(19) = 482984 (8000)
      Used(20) = 490224 (7240)
      Used(21) = 498224 (8000)
      Used(22) = 506976 (8752)
      Used(23) = 514656 (7680)
      Used(24) = 522984 (8328)
      Used(25) = 530984 (8000)
      Used(26) = 536936 (5952)
      Used(27) = 546544 (9608)
      Used(28) = 552216 (5672)
      Used(29) = 561504 (9288)
      Used(30) = 569504 (8000)
      Used(31) = 577304 (7800)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;
      import javax.swing.plaf.basic.BasicComboPopup;

      public class MemoryLeakTest {
          public MemoryLeakTest(int count, Class cls) {
              Object obj = null;
              for (int i = 0; i < count; i++) {
                  try {
                      obj = cls.newInstance();
                  } catch (InstantiationException e1) {
                  } catch (IllegalAccessException e1) {
                  }
              }
              try {
                  Thread.sleep(2000);
              } catch (InterruptedException e) {
              }
          }
          
          public static void main(String[] x) {
              if(x.length < 1) {
                  System.out.println("USAGE: java MemoryLeakTest <class>");
                  return;
              }
              
              try {
                  Class classForTest = Class.forName(x[0]);
                  long used = 0;
                  for (int i = 0; i < 300; i++) {
                      System.gc();
                      new MemoryLeakTest(1000, classForTest);
                      System.gc();
                      long usedThisTime =
                          Runtime.getRuntime().totalMemory()
                          - Runtime.getRuntime().freeMemory();
                      if (i == 0) {
                          System.out.println("Used("+i+") = "+usedThisTime);
                      } else {
                          System.out.println("Used("+i+") = "+usedThisTime
                              +" ("+(usedThisTime - used)+")");
                      }
                      used = usedThisTime;
                  }
                  
              } catch (Exception e) {
                  e.printStackTrace();
              }
              System.exit(0);
          }
      }

      ---------- END SOURCE ----------
      (Incident Review ID: 232494)
      ======================================================================

            bchristi Brent Christian
            jleesunw Jon Lee (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: