title: Memory Leak with Swing Drag and Drop
body: <p>I have a JFrame that accepts top-level drops of files. However after a drop has occurred, references to the frame are held indefinitely inside some Swing internal classes. I believe that disposing of the frame should release all of its resources, so what am I doing wrong?</p>
  
  <p>Example </p>
  
  <pre><code>import java.awt.datatransfer.DataFlavor;
  import java.io.File;
  import java.util.List;
  
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.TransferHandler;
  
  public class DnDLeakTester extends JFrame {
      public static void main(String[] args) {
          new DnDLeakTester();
  
          //Prevent main from returning or the jvm will exit
          while (true) {
              try {
                  Thread.sleep(10000);
              } catch (InterruptedException e) {
  
              }
          }
      }
      public DnDLeakTester() {
          super("I'm leaky");
  
          add(new JLabel("Drop stuff here"));
  
          setTransferHandler(new TransferHandler() {
              @Override
              public boolean canImport(final TransferSupport support) {
                  return (support.isDrop() &amp;&amp; support
                          .isDataFlavorSupported(DataFlavor.javaFileListFlavor));
              }
  
              @Override
              public boolean importData(final TransferSupport support) {
                  if (!canImport(support)) {
                      return false;
                  }
  
                  try {
                      final List&lt;File&gt; files = (List&lt;File&gt;) 
                              support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
  
                      for (final File f : files) {
                          System.out.println(f.getName());
                      }
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
  
                  return true;
              }
          });
  
          setDefaultCloseOperation(DISPOSE_ON_CLOSE);
          pack();
          setVisible(true);
      }
  }
  </code></pre>
  
  <p>To reproduce, run the code and drop some files on the frame. Close the frame so it's disposed of. </p>
  
  <p>To verify the leak I take a heap dump using JConsole and analyse it with the <a href="http://www.eclipse.org/mat/">Eclipse Memory Analysis tool</a>. It shows that sun.awt.AppContext is holding a reference to the frame through its hashmap. It looks like TransferSupport is at fault.</p>
  
  <p><a href="http://img402.imageshack.us/img402/4444/dndleak.png">image of path to GC root http://img402.imageshack.us/img402/4444/dndleak.png</a></p>
  
  <p>What am I doing wrong? Should I be asking the DnD support code to clean itself up somehow?</p>
  
  <p>I'm running JDK 1.6 update 19.</p>