Possiedo un JFrame che accetta gocce di file di livello superiore. Tuttavia, dopo che si è verificata una caduta, i riferimenti al frame vengono mantenuti indefinitamente all'interno di alcune classi interne di Swing. Credo che lo smaltimento della cornice dovrebbe liberare tutte le sue risorse, quindi cosa sto facendo di sbagliato?Perdita di memoria con Swing Drag and Drop
Esempio
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);
}
}
Per riprodurre, eseguire il codice e rilasciare alcuni file sul telaio. Chiudi la cornice in modo che sia eliminata.
Per verificare la perdita, prendo un dump dell'heap utilizzando JConsole e analizzandolo con Eclipse Memory Analysis tool. Mostra che sun.awt.AppContext ha un riferimento al frame tramite la sua hashmap. Sembra che TransferSupport sia in errore.
image of path to GC root http://img402.imageshack.us/img402/4444/dndleak.png
Che cosa sto facendo di sbagliato? Dovrei chiedere al codice di supporto DnD di pulirsi in qualche modo?
Io corro JDK 1.6 update 19.
Sto iniziando a pensare che si tratti di un bug JVM. Le classi DnD rilevanti non hanno il codice per cancellare i riferimenti incriminati, quindi a meno che DropHandler non sia rimosso dalla mappa di AppContext in qualche modo (non capisco davvero la classe), la perdita rimarrà. – tom
Questo post sul forum descrive un problema simile [http://forums.java.net/jive/thread.jspa?messageID=276311]. Non ha ricevuto risposte. – tom