Ich habe einen JFrame, der Top-Level-Tropfen von Dateien akzeptiert. Nach einem Absturz werden Verweise auf den Rahmen jedoch innerhalb bestimmter interner Swing-Klassen unbegrenzt beibehalten. Ich glaube, dass die Freigabe des Rahmens alle Ressourcen freisetzen sollte. Was mache ich also falsch?Speicherleck mit Swing Drag & Drop
Beispiel
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() && support
.isDataFlavorSupported(DataFlavor.javaFileListFlavor));
}
@Override
public boolean importData(final TransferSupport support) {
if (!canImport(support)) {
return false;
}
try {
final List<File> files = (List<File>)
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);
}
}
Um den Code und legen Sie einige Dateien auf dem Rahmen zu reproduzieren, laufen. Schließen Sie den Rahmen, damit er entsorgt wird.
Um das Leck zu überprüfen, nehme ich einen Heap-Dump mit JConsole und analysiere es mit der Eclipse Memory Analysis tool. Es zeigt, dass sun.awt.AppContext einen Verweis auf den Frame durch seine Hashmap hält. Es sieht so aus, als wäre TransferSupport schuld.
image of path to GC root http://img402.imageshack.us/img402/4444/dndleak.png
Was mache ich falsch? Sollte ich den DnD-Support-Code bitten, sich irgendwie aufzuräumen?
Ich bin mit JDK 1.6 Update 19
Ich fange an zu denken, dass dies ein JVM-Bug ist. Die relevanten DnD-Klassen haben keinen Code, um die fehlerhaften Verweise zu löschen. Wenn also der DropHandler nicht irgendwie aus der AppContext-Map entfernt wird (ich verstehe diese Klasse nicht wirklich), bleibt das Leck bestehen. – tom
Dieser Forenbeitrag beschreibt ein ähnliches Problem [http://forums.java.net/jive/thread.jspa?messageID=276311]. Es hat keine Antworten erhalten. – tom