сборка мусора Java в диалоге

* Сейчас я сталкиваюсь с очень странной проблемой Java GC, когда пытаюсь создать кнопку в JFrame, и когда я нажимаю кнопку, она отображает JDialog, который должен иметь дело с некоторыми изображениями и отображать их, и требует почти 200 МБ памяти. Но проблема в том, что когда я закрываю диалог и снова открываю его, иногда это вызывает java.lang.OutOfMemoryError. (не каждый раз)

Пытаясь решить проблему, я упрощаю эту проблему и провожу некоторый эксперимент,что вызывает у меня большее замешательство.

Код, который я использовал в своем «эксперименте», показан ниже. Когда я нажимаю кнопку в кадре, я выделяю 160M памяти для целочисленного массива и отображаю диалоговое окно,Но если я закрою диалог и снова открою его, появится OutOfMemoryError. Я корректирую код и результат:

Если я не создаю диалог и не показываю его, проблем с памятью нет.Если я добавлю windowsCloseListener, который вызывает System.gc () к диалогу, проблем с памятью нет.

Если я вызываю System.gc () в методе run (), возникает проблема с памятью.

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

Я читал о многих статьях, которые описывают, как работает Java-сборщик мусора. Я думаю, что если Java пытается выделить некоторое пространство в куче, и у него недостаточно свободного места, java сделает gc, и если к объекту нельзя получить доступ из корня gc через «граф GC», в котором ребро из от u до v у вас есть ссылка на v, root - это что-то в рабочем стеке потоков, или нативные ресурсы. Это бесполезно и квалифицировано для сбора GC java.

Теперь проблема в том, Когда я нажимаю кнопку и пытаюсь создать массив Integer, массив Integer, который я создаю в прошлый раз, безусловно, пригоден для сбора в GC java. Так почему это вызвало ошибку.

Прошу прощения за такое длинное описание ... У меня нет особой тактики в постановке проблемы, поэтому просто пытаюсь прояснить это.

Кроме того, параметр, который я использовал для запуска jvm: «java –Xmx256m»

Ответы на вопрос(2)

Ваш ответ на вопрос