Mam JFrame, która akceptuje najwyższego poziomu krople plików. Jednak po wystąpieniu kropli odniesienia do ramki są przechowywane bez końca w niektórych klasach wewnętrznych Swinga. Uważam, że pozbycie się ramy powinno uwolnić wszystkie jej zasoby, więc co robię źle?Wyciek pamięci z Swing Przeciągnij i upuść
Przykład
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);
}
}
Aby odtworzyć, uruchomić kod i upuścić kilka plików na ramie. Zamknij ramkę, aby się pozbyć.
Aby zweryfikować wyciek, wykonuję zrzut sterty za pomocą programu JConsole i analizuję go za pomocą Eclipse Memory Analysis tool. Pokazuje, że sun.awt.AppContext zawiera odwołanie do ramki poprzez swoją mapę. Wygląda na to, że TransferSupport jest wadliwy.
image of path to GC root http://img402.imageshack.us/img402/4444/dndleak.png
Co robię źle? Czy powinienem poprosić o kod obsługi DnD, aby jakoś się oczyścił?
biegnę JDK 1.6 aktualizacji 19.
Zaczynam myśleć, że to błąd JVM. Odpowiednie klasy DnD nie mają kodu, aby usunąć niepożądane odwołania, więc jeśli dropHandler nie zostanie w jakiś sposób usunięty z mapy AppContext (tak naprawdę nie rozumiem tej klasy), wyciek pozostanie. – tom
Ten wpis na forum opisuje podobny problem [http://forums.java.net/jive/thread.jspa?messageID=276311]. Nie otrzymał odpowiedzi. – tom