我有一个接受顶级文件滴的JFrame。但是,在发生拖放之后,对框架的引用将无限期地保留在某些Swing内部类中。我相信处置这个框架应该释放它的所有资源,所以我做错了什么?内存泄漏与摆动拖放
例
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);
}
}
要重现,运行代码并丢弃帧上的一些文件。关闭框架,以便处理它。
要验证泄漏,我使用JConsole进行堆转储,并使用Eclipse Memory Analysis tool对其进行分析。它显示sun.awt.AppContext通过它的散列映射来保存对帧的引用。它看起来像TransferSupport有问题。
image of path to GC root http://img402.imageshack.us/img402/4444/dndleak.png
我在做什么错?我应该问DnD支持代码以某种方式清理自己吗?
我运行JDK 1.6更新19
我开始认为这是一个JVM错误。相关的DnD类没有代码来清除有问题的引用,所以除非DropHandler以某种方式从AppContext的映射中移除(我并不真正了解该类),否则泄漏将保留。 – tom 2010-05-12 00:32:54
这个论坛帖子描述了一个类似的问题[http://forums.java.net/jive/thread.jspa?messageID=276311]。它没有回应。 – tom 2010-05-12 00:47:17