śmieci java zbierające się w oknie dialogowym
* Teraz, gdy próbuję zrobić przycisk w ramce JFrame, napotykam bardzo dziwny problem z java GC, a gdy klikam ten przycisk, wyświetla się JDialog, który musi radzić sobie z niektórymi obrazami i wyświetlać je oraz potrzebuje prawie 200M pamięci. Ale problem polega na zamknięciu okna dialogowego i ponownym otwarciu go, czasami powoduje java.lang.OutOfMemoryError. (nie za każdym razem)
Próbując rozwiązać problem, upraszczam ten problem i eksperymentuję,co powoduje, że jestem bardziej zdezorientowany.
Kod, którego użyłem w moim „eksperymencie”, pokazano poniżej. Kiedy klikam przycisk w ramce, przydzielam 160M pamięci na tablicę liczb całkowitych i wyświetlam okno dialogowe,Ale jeśli zamknę okno i otworzę je ponownie, pojawi się OutOfMemoryError. Dostosowuję kod, a wynikiem jest:
Jeśli nie utworzę okna dialogowego i nie pokażę, nie ma problemu z pamięcią.Jeśli dodam windowsCloseListener, który wywołuje System.gc () do okna dialogowego, nie ma problemu z pamięcią.Jeśli wywołam System.gc () w metodzie run (), pojawia się problem z pamięcią.
public class TestController {
int[] tmp;
class TDialog extends JDialog {
public TDialog() {
super();
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
// If I uncommment this code, OutOfMemoryError seems to dispear in this situation
// But I'm sure it not a acceptable solution
/*
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("windowsclose");
TDialog.this.dispose();
System.gc();
}
});
*/
}
}
TDialog dia;
public void run() {
// If I do System.gc() here, OutOfMemoryError still exist
// System.gc();
tmp = new int[40000000];
for (int i = 0; i < tmp.length; i += 10)
tmp[i] = new Random().nextInt();
dia = new TDialog();
dia.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(200, 200);
JButton button = new JButton("button");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TestController controller = new TestController();
controller.run();
controller = null;
}
});
frame.add(button);
frame.setVisible(true);
}
});
}
}
Czytałem o wielu artykułach, które opisują, jak działa GC java. Myślę, że jeśli java próbuje przydzielić trochę miejsca w stercie i nie ma wystarczającej ilości wolnego miejsca, java zrobi gc i jeśli obiekt nie będzie dostępny z poziomu roota gc przez „wykres GC”, w którym krawędź od u do v reprezentują u mają odniesienie do v, root jest czymś w stosie roboczym wątku lub rodzimymi zasobami, jest bezużyteczny i kwalifikowany do zbierania przez GC java.
Teraz problem jest Gdy klikam przycisk i próbuję utworzyć tablicę liczb całkowitych, tablica Integer, którą utworzyłem ostatnio, z pewnością kwalifikuje się do pobrania przez GC java. Dlaczego więc spowodował błąd.
Przepraszam za tak długi opis… Nie mam zbyt wielu taktyk w zadawaniu problemów, więc po prostu staram się to wyjaśnić.
Poza tym parametr, którego użyłem do uruchomienia jvm, to „java –Xmx256m”