ś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”

questionAnswers(2)

yourAnswerToTheQuestion