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

gratuitous use of addNotify() causes memory leaks and potential crashes

XMLWordPrintable

    • generic, sparc
    • solaris_2.5.1

      Most of the addNotify() methods for the various awt components
      will create a peer without first checking to see if a peer already
      exists for the object.

      For example,

          public void addNotify() {
              peer = getToolkit().createButton(this);
              super.addNotify();
          }

      This has a few bad side effects:
      - if a peer already existed, it is overwritten with the new peer.
      The net effect is that there are no longer any references to the
      peer (that gc() will find) so the object may be collected and its
      handle reused. Note that the native widget will not be free'd in
      this case causing a memory leak.

      - the old entry for the peer will never be removed from the
      widget mapping table, awt_winfo. This table contains entries
      which map motif widgets to their corresponding peers. Because the
      old widget is not deleted either, if an event happens to be directed
      to that old widget, the awt will try to send the event to the
      corresponding peer (which may have been garbage collect - or worse yet-
      garbage collected and reused). This can cause random crashes.

      Note that even though the documentation discourages calling addNotify directly
      for most components, for components such as Frame, it does not. If this
      is simply an omission in the docs, then perhaps this bug should be reclassified.

      Also note that the code must be using addNotify() incorrectly in some way
      for this to occur (i.e. calling addNotify() more than once for a given
      component). This is not that hard to do since show() and pack() both call
      addNotify() as well.

      Here is simple program which demonstrates the memory leak....


      public class ThreadTest
      {

              public static void main(String args[])
              {
                      Frame f;

                      while (true) {
                              f = new Frame();
                              f.resize(100, 100);
                              f.addNotify();
                              f.addNotify();
                              f.addNotify();
                              f.addNotify();
                              f.addNotify();
                              f.addNotify();
                              f.pack();
                              f.show();
                              f.dispose();
                              System.gc();
                      }
              }
      }

      Note that show() and pack() have the same problem since they are no
      longer synchronized. See bug #4041235.

            rramsunw Ranganathan Ram (Inactive)
            duke J. Duke
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: