java recolección de basura en el diálogo

* Ahora estoy encontrando un problema muy extraño en el GC java cuando intento hacer un botón en un JFrame, y cuando hago clic en el botón, muestra un JDialog que necesita tratar y mostrar algunas imágenes y necesita casi 200M de memoria. Pero el problema es que cuando cierro el cuadro de diálogo y lo vuelvo a abrir, a veces causa java.lang.OutOfMemoryError. (no todas las veces)

Tratando de resolver el problema, simplifico este problema y hago algunos experimentos,Lo que me causa más confusión.

El código que usé en mi "experimento" se muestra a continuación. Cuando hago clic en un botón en un marco, asigno 160M de memoria para una matriz de enteros, y visualizo un diálogo,Pero si cierro el cuadro de diálogo y lo vuelvo a abrir, aparece OutOfMemoryError. Ajustando el código y el resultado es:

Si no creo el cuadro de diálogo y lo muestro, no hay problema de memoria.Si agrego un windowsCloseListener que invoca System.gc () al cuadro de diálogo, no hay problema de memoria.

Si invoco System.gc () en el método run (), se muestra un problema de memoria.

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);
      }
    });
  }
}

He leído sobre muchos artículos que describen cómo funciona el GC de Java. Creo que si java intenta asignar algo de espacio en el montón y no tiene suficiente espacio libre, java hará gc, y si no se puede acceder a un objeto desde la raíz de gc a través del "gráfico GC", en el que se muestra un borde desde u para v representa u tiene una referencia a v, root es algo en la pila de trabajo de un hilo, o recursos nativos, es inútil y está calificado para ser recopilado por el GC de java.

Ahora el problema es Cuando hago clic en el botón y trato de crear una matriz Integer, la matriz Integer que creo la última vez ciertamente está calificada para ser recopilada por el GC de java. Entonces, ¿por qué causó el error.

Pido disculpas por una descripción tan larga ... No tengo muchas tácticas para preguntar el problema, así que solo trato de aclararlo.

Además, el parámetro que utilicé para iniciar jvm es "java –Xmx256m"

Respuestas a la pregunta(2)

Su respuesta a la pregunta