【发布时间】:2011-02-18 00:16:16
【问题描述】:
我有一个接受顶级文件的 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 类没有清除违规引用的代码,因此除非以某种方式从 AppContext 的映射中删除 DropHandler(我不太了解该类),否则泄漏将继续存在。
-
这个论坛帖子描述了一个类似的问题 [forums.java.net/jive/thread.jspa?messageID=276311].它没有得到任何回应。
标签: java swing memory-leaks drag-and-drop