сборка мусора 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»