powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / OutOfMemory и прочие неприятности для GUI
20 сообщений из 20, страница 1 из 1
OutOfMemory и прочие неприятности для GUI
    #34819072
Турборуль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Никак не могу понять, как защитить GUI приложение от проблем с глобальными сбоями типа OutOfMemory. Хочется чтобы такие сбои не приводили к непредсказуемому поведению приложения (типа застрелов), а просто позволить пользователю дождаться более удачного момента, чтобы выпполнить действие.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
 import  java.util.LinkedList;

 import  java.awt.FlowLayout;

 import  java.awt.event.ActionEvent;

 import  javax.swing.AbstractAction;
 import  javax.swing.JFrame;
 import  javax.swing.JButton;
 import  javax.swing.JOptionPane;
 import  javax.swing.SwingUtilities;

 public   class  Failure
 extends  JFrame
{
	 private  LinkedList garbage =  new  LinkedList();
	
	 private  Thread eater =  new  Thread()
	{
		 private   long  sleep =  1 ;
		
		 public   void  run()
		{
			 while  (true)
			{
				 try 
				{
					garbage.add( new   int [ 250 ]);
					sleep(sleep);
				}
				 catch  (InterruptedException e)
				{
					 super .interrupt();
					 break ;
				}
				 catch  (Throwable e)
				{
					// Не будем насиловать GC :)
					sleep =  10000 ;
				}
			}
			
			garbage.clear();
		}
	};
	
	 private  Thread.UncaughtExceptionHandler globalExceptionHandler =  new  Thread.UncaughtExceptionHandler()
	{
		 private   static   final  String errorText = "Out of memory!";
		
	     public   void  uncaughtException(
	        Thread t, 
	        Throwable e)
	    {
	    	// Здесь можно было бы создать диалог об ошибке, вместо этого сообщения в консоль
	    	System.out.println(errorText);
	    }
	};
	
	
	 public  Failure()
	{
		Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler);
		
		setLayout( new  FlowLayout());
		JButton buttonEat =  new  JButton( new  AbstractAction("Eat")
		{
			 public   void  actionPerformed(
				ActionEvent event)
			{
				((JButton) event.getSource()).setEnabled(false);
				eater.start();
			}
		});
		JButton buttonRelease =  new  JButton( new  AbstractAction("Release")
		{
			 public   void  actionPerformed(
				ActionEvent event)
			{
				eater.interrupt();
			}
		});
		
		JButton buttonTest =  new  JButton( new  AbstractAction("Test")
		{
			 public   void  actionPerformed(
				ActionEvent event)
			{
				// Должно привести к OutOfMemory, будет перехвачено в глобальном перехватчике
				JOptionPane.showMessageDialog(Failure. this , "Test");
			}
		});
		
		add(buttonEat);
		add(buttonRelease);
		add(buttonTest);
	}
	
	 public   static   void  main(
		String[] args)
	{
		SwingUtilities.invokeLater( new  Runnable()
		{
			 public   void  run()
			{
				Failure f =  new  Failure();
				f.pack();
				f.setLocationRelativeTo( null );
				f.setVisible(true);
			}
		});
	}
}

Однако в этом примере после запуска потока, сжирающего память не удается даже нажать на кнопку Release... после минуты усиленной работы GC приложение просто отстреливает JFrame, хотя джава машина продолжает работать...
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34820747
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
по моему когда прилетает OutOfMemory, тогда уже бесполезно с ней бороться. У тебя JVM захлебнулась и приложению кирдык. Нужно до этого просто не доводить и следить за тем чтобы ненужные объекты становились доступны для gc.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34820830
Juga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
может -Xmx поможет отцу русской демократии, хотя это и не выход но иногда помогает, когда код уже вылизан.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34822016
Турборуль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vas0по моему когда прилетает OutOfMemory, тогда уже бесполезно с ней бороться. У тебя JVM захлебнулась и приложению кирдык. Нужно до этого просто не доводить и следить за тем чтобы ненужные объекты становились доступны для gc.

Проблема не в ненужных объектах, а в физическом недостатке памяти, который просто нужно временно пережить, не умерев на пути к светлому будущему :) Все-таки ОС, БД, разные сетевые сервисы не стреляются и не умирают при недостатке памяти, а просто временно отказывают в обслуживании, неужели это невозможно для ГУИ?
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34822037
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никак. OutOufMemory Error возникает только если нет возможности найти память для объекта после выполнение сборщика мусора. Другими словами, сначала освобождается, что можется, и если после этого не хватает памяти - вызывается ошибка.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34823918
wessen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все зависит от задачи, которую решает приложение. Если перед выполнением задачи возможно достаточно точно оценить, сколько потребуется памяти, то перед выполнением такой задачи можно посмотреть сколько места осталось в куче и если будет видно, что его не хватит для выполнения задачи, то не выполнять ее. Так делает JEdit к примеру, если попытаться им открыть очень большой файл, то он вывидит диалог в котором написано, что операцию выполнить невозможно и ссылка на мануал - как дать приложению больше памяти.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34824167
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. OOM пролетает в eater thread, поэтому если надо поставить default exception handler, его надо ставить например при создании потока eater. При этом есессно не нужно ловить Throwable (это вообще дурной стиль).
2. Когда случится OOM, eater thread будет в состоянии terminated и вызов interrupted - что мертвому припарка.
3. "приложение просто отстреливает JFrame, хотя джава машина продолжает работать"
посмеялсо. RTFM
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34825478
Турборуль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Timm1. OOM пролетает в eater thread, поэтому если надо поставить default exception handler, его надо ставить например при создании потока eater. При этом есессно не нужно ловить Throwable (это вообще дурной стиль).

Вы не поняли как работает код. Eater thread постоянно доедает всю доступную память, поэтому я не хочу чтобы он завершался ни при каких условиях и ловлю Throwable (в т.ч. OutOfMemoryError), поймав который просто уменьшаю интенсивность сжирания памяти. Речь не идет о тоне и пр. сторонах программирования, представлен конкретный код, есть конкретная задача -- заставить его работать так, как он должен (по моему мнению) работать.

Timm
2. Когда случится OOM, eater thread будет в состоянии terminated и вызов interrupted - что мертвому припарка.

См. п. 1. eater thread никогда не будет в состоянии terminated.

Timm
3. "приложение просто отстреливает JFrame, хотя джава машина продолжает работать"
посмеялсо. RTFM
И кто же интересно вызывает close фрейма и с какого перепугу? Это типа нормальное поведение Swing'а закрывать фреймы когда ему вздумается?
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34825494
Турборуль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wessenВсе зависит от задачи, которую решает приложение. Если перед выполнением задачи возможно достаточно точно оценить, сколько потребуется памяти, то перед выполнением такой задачи можно посмотреть сколько места осталось в куче и если будет видно, что его не хватит для выполнения задачи, то не выполнять ее. Так делает JEdit к примеру, если попытаться им открыть очень большой файл, то он вывидит диалог в котором написано, что операцию выполнить невозможно и ссылка на мануал - как дать приложению больше памяти.
Это было бы вариантом для монолитного приложения, но когда какой-то модуль начинает сжирать память (например из за ошибки программиста или ошибки пользователя -- запустил слишком сложную операцию), то я совершенно не хочу, чтобы данные в других модулях были потеряны.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34825762
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Турборуль Timm1. OOM пролетает в eater thread, поэтому если надо поставить default exception handler, его надо ставить например при создании потока eater. При этом есессно не нужно ловить Throwable (это вообще дурной стиль).

Вы не поняли как работает код.
Это точно.
Твой код - memory leak. Выполняется операция, N раз, при этом расходуемая память планомерно растет после каждого выполнения, и не отдается. Выхода из _такой_ ситуации нет ни для обычных, ни для GUI-шных приложений, хоть гиг выдели, хоть два. рано или поздно все умрет.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34826149
wessen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Турборуль
Это было бы вариантом для монолитного приложения, но когда какой-то модуль начинает сжирать память (например из за ошибки программиста или ошибки пользователя -- запустил слишком сложную операцию), то я совершенно не хочу, чтобы данные в других модулях были потеряны.

memory leak это fatal error и никак иначе, такие баги в идеале должны отлавливаться на этапе тестирования и отладки, а ты так рассуждаешь, как-будто это обычное дело. и вообще, если возникает исключение, которое наследуется от Error, то JVM хана, она не в рабочем состоянии, ничего сделать уже нельзя, только restart. почитай вобщем java doc.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34832455
Турборуль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wessen Турборуль
Это было бы вариантом для монолитного приложения, но когда какой-то модуль начинает сжирать память (например из за ошибки программиста или ошибки пользователя -- запустил слишком сложную операцию), то я совершенно не хочу, чтобы данные в других модулях были потеряны.

memory leak это fatal error и никак иначе, такие баги в идеале должны отлавливаться на этапе тестирования и отладки, а ты так рассуждаешь, как-будто это обычное дело. и вообще, если возникает исключение, которое наследуется от Error, то JVM хана, она не в рабочем состоянии, ничего сделать уже нельзя, только restart. почитай вобщем java doc.

Т.е. то, что в c/c++ решается кодом
Код: plaintext
1.
2.
  garbage = malloc(n);
  if (!garbage) return E_OUT_OF_MEMORY;

в java решается перезапуском машины? Забавно... Почитал javadoc, но ничего похожего там не нашел.

Timm Турборуль Timm1. OOM пролетает в eater thread, поэтому если надо поставить default exception handler, его надо ставить например при создании потока eater. При этом есессно не нужно ловить Throwable (это вообще дурной стиль).

Вы не поняли как работает код.
Это точно.
Твой код - memory leak. Выполняется операция, N раз, при этом расходуемая память планомерно растет после каждого выполнения, и не отдается. Выхода из _такой_ ситуации нет ни для обычных, ни для GUI-шных приложений, хоть гиг выдели, хоть два. рано или поздно все умрет.

Зачем так прикапывать к тестовому примеру и вечно уходить с основной темы в сторону memory leak? Ну замените eater thread на следующий.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
 private  Thread eater =  new  Thread()
	{
		 public   void  run()
		{
                     try  {
		         int [] bigHeap =  new   int [очень много памяти];
		        // Сделать очень долгую, требующую много памяти (но не больше, чем уже выделено в bigHeap) работу в фоновом режиме
                     }
                      catch  (OutOfMemoryError)
                     {
                        // callback
                     }
		}
	};

Причем поток этот запускается в модуле, о существовании которого другие модули даже не догадываются.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34832499
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Турборуль
Зачем так прикапывать к тестовому примеру и вечно уходить с основной темы в сторону memory leak? Ну замените eater thread на следующий.

Ни в коем случае не ухожу от темы. Пойми, что твой код _расходует память и не освобождает ее_
андестенд?
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34832693
Турборуль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Timm Турборуль
Зачем так прикапывать к тестовому примеру и вечно уходить с основной темы в сторону memory leak? Ну замените eater thread на следующий.

Ни в коем случае не ухожу от темы. Пойми, что твой код _расходует память и не освобождает ее_
андестенд?

Я заменил код на тот, который расходует и освобождает, что изменилось?
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34832947
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.devx.com/tips/Tip/5542
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34835204
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Турборуль Timm Турборуль
Зачем так прикапывать к тестовому примеру и вечно уходить с основной темы в сторону memory leak? Ну замените eater thread на следующий.

Ни в коем случае не ухожу от темы. Пойми, что твой код _расходует память и не освобождает ее_
андестенд?

Я заменил код на тот, который расходует и освобождает, что изменилось?
В чем проблема в измененном коде eater'a? я ее не вижу.
Еще раз:
"Хочется чтобы такие сбои не приводили к непредсказуемому поведению приложения "
такого поведения в общем случае обеспечить невозможно.
Какую то защиту можно организовать, если при старте приложения создать абсолютно все объекты которые понадобятся при обработке OOM и в обработке оперировать только ими. И то не во всех случаях поможет. лучше фиксить проблемы с памятью.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34835640
Турборуль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Timm
В чем проблема в измененном коде eater'a? я ее не вижу.


В том, что если выделить достаточно много памяти, свинг застрелит фрейм, если кликнуть по кнопке.

Timm
Еще раз:
"Хочется чтобы такие сбои не приводили к непредсказуемому поведению приложения "
такого поведения в общем случае обеспечить невозможно.
Какую то защиту можно организовать, если при старте приложения создать абсолютно все объекты которые понадобятся при обработке OOM и в обработке оперировать только ими. И то не во всех случаях поможет. лучше фиксить проблемы с памятью.

Ок, тогда может лучше обсудить как реализуют такую защиту реальные приложения? Например, графические оболочки. Я не уверен насчет kde/gnome, так как редко их использовал, но винда точно не начинает закрывать окна при недостатке памяти и уж тем более не застреливает все на своем пути.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34835648
Турборуль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonidvhttp://www.devx.com/tips/Tip/5542

1) это не вариант для многопоточных приложений
2) это не вариант для крупных приложений, не вставлять же такую проверку после каждой инструкции, которая что-то создает? Хочется универсальный удобный механизм типа UncaughtExceptionHandler.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34835650
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Турборуль Timm
В чем проблема в измененном коде eater'a? я ее не вижу.


В том, что если выделить достаточно много памяти, свинг застрелит фрейм, если кликнуть по кнопке.

1. версия JVM и ОС
2. параметры запуска
3. полностью код который к этому приводит.
Я такого не наблюдал.
...
Рейтинг: 0 / 0
OutOfMemory и прочие неприятности для GUI
    #34835726
Фотография 1024
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
наверна у тебя не фрейм убивается а поток который забрал всю память. Т.е. весь AWT
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / OutOfMemory и прочие неприятности для GUI
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]