Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Нужно ли в java освобождать объекты?


Автор: Barvetal 31.8.2006, 22:26
Всем привет!

Раньше программил на С++. Там все созданные объекты нужно было освобождать. В java вроде как не надо.

Однако возникает вопрос. Может, все-таки объекты освобождать вручную нужно? А то JavaHeapSpaceException уже задолбал. Даю 256 метров памяти, вроде данных не так уж и много...

Вобщем, вопрос такой. Нужно ли в java освобождать объекты?

Всем спасибо!

Автор: LSD 31.8.2006, 22:43
Нужно обнулять ссылки на неиспользуемые объекты, и тогда garbage collector их сможет убрать.

Автор: Ch0bits 31.8.2006, 23:01
Он их сразу убирает или как-нибудь потом в фоне?

Автор: LSD 31.8.2006, 23:10
Когда будет вызван GC не известно (зависит от реализации JVM), но гарантируется что GC будет вызван перед тем как будет выкинуто OutOfMemoryError.

Автор: chief39 1.9.2006, 09:40
Можно так же ускорить вызов коллектора(но не гарантировать что сейчас же ) строчкой:
Код

System.gc();

Автор: Tony 1.9.2006, 11:35
Цитата(Barvetal @ 31.8.2006,  22:26)
Всем привет!

Раньше программил на С++. Там все созданные объекты нужно было освобождать. В java вроде как не надо.

Однако возникает вопрос. Может, все-таки объекты освобождать вручную нужно? А то JavaHeapSpaceException уже задолбал. Даю 256 метров памяти, вроде данных не так уж и много...

Вобщем, вопрос такой. Нужно ли в java освобождать объекты?

Всем спасибо!

Может код кривой?

Автор: Lerm 1.9.2006, 23:46
Цитата(chief39 @ 1.9.2006,  09:40)
Можно так же ускорить вызов коллектора(но не гарантировать что сейчас же ) строчкой:
Код

System.gc();

Только лучше всё таки так не делать - не стоит явно вмешиваться в работу GC. Это может потребоваться только в очень ограниченном количестве случаев.

Появление проблем с памятью в большинстве случаев говорит о том, что либо имеется её утечка (копим неиспользуемые объекты), либо памяти просто выделено недостаточно (не рассчитали нужный объем, необходимый для хранения всех требуемых объектов). Кстати, я в первый раз слышу про такой Exception - JavaHeapSpaceException. Какой точно Exception выскакивает - OutOfMemoryError или что-то другое? На Unix-системах иногда вылетает Exception c not enough space при попытке вызвать сторонний процесс (fork не может память зарезервировать). А иногда (это особенно характерно для серверов приложений) OutOfMemoryError может свидетельствовать не о недостатке кучи, а нехватки Permanent-области. Так что без дополнительных сведений о приложении и том, как оно работает с памятью - сказать что-нибудь по проблеме сложно.

Автор: JUncle 2.9.2006, 14:39
Цитата(Lerm @  1.9.2006,  23:46 Найти цитируемый пост)
Это может потребоваться только в очень ограниченном количестве случаев.

Например при отладке. В других случаях его применение сомнительно. 
(Хотя, нравится как в IDEA сделано - иконка с корзиной, нажатие на которую вызывает gc - но там это не грозит потерей производительности - ибо сам нажал, сам и подождешь  smile)

Автор: COVD2 2.9.2006, 17:12
Цитата

Только лучше всё таки так не делать - не стоит явно вмешиваться в работу GC. Это может потребоваться только в очень ограниченном количестве случаев.


Java широко используется в серверных приложениях. Серверные приложения работают как правило круглосуточно. Причем активность пользователей может носить периодический характер. Например, максимум запросов днем и минимум - ночью. В этой ситуации естественно хочется явно запускать коллектор, чтобы в периоды простоя он почистил память, на всякий случай, чтобы в периоды активности ему меньше работы было. Однако явно управлять уборщиком мусора нельзя. Можно только "порекомендовать" ему заняться делом в виде многократных вызовов System.gc(). 

Одной из стратегий в данной ситуации является аккуратное программирование - по возможности "не мусорить". Не создавать без особой нужды новые обьекты, использовать пулы. Однако это идет в разрез с концепцией обьектно-ориентированного программирования. Как и любой другой тюнинг, это повышает эффективность, но делает программу более сложной. В то же время в последних версиях java уборка мусора может реализовываться в фоновом режиме, что менее болезненно для приложения.  

Автор: Lerm 3.9.2006, 11:27
Цитата
Java широко используется в серверных приложениях. Серверные приложения работают как правило круглосуточно. Причем активность пользователей может носить периодический характер. Например, максимум запросов днем и минимум - ночью. В этой ситуации естественно хочется явно запускать коллектор, чтобы в периоды простоя он почистил память, на всякий случай, чтобы в периоды активности ему меньше работы было. Однако явно управлять уборщиком мусора нельзя. Можно только "порекомендовать" ему заняться делом в виде многократных вызовов System.gc(). 


Ну, для нормального серверного приложения одно выполнение FullGC ночью вероятно ничего не даст - в течение дня он будет вызван не один раз. Я вижу применение вызова System.gc() только в тестовых и отладочных целях - когда мы хотим, скажем, замерить потребление памяти при выполнении некоторой операции.

Цитата
В то же время в последних версиях java уборка мусора может реализовываться в фоновом режиме, что менее болезненно для приложения.


Смотря для какого приложения. Для интерактивного приложения, которое должно всегда отзываться на действия пользователя - вероятно да, более полезно. Для серверных приложений, которые обрабатывают поток запросов, это хуже - проще в какой-то момент прерваться, бросить все силы на сборку мусора, а затем вернуться к работе - сумарная пропускная способность окажется выше.

Автор: COVD2 3.9.2006, 16:55
Цитата

Ну, для нормального серверного приложения одно выполнение FullGC ночью вероятно ничего не даст - в течение дня он будет вызван не один раз.


Да, для нормального приложения, которое ни в чем себе не отказывая плодит одноразовые обьекты, это не поможет. А постоянные обьекты (кэш) в некоторых случаях ведут себя вполне предсказуемо. И можно определенно сказать сколько надо памяти приложению в начале цикла (утром) и насколько она возрастет к вечеру. 
...

Цитата

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


Вот вы прерветесь, а входящие запросы придется в буфер класть, и буфер переполнится, и запросы потеряются.  smile Да, творческое это дело.

И все же жаль, что нет в java способов  короткой и беспощадной расправы с обьектами. Видимо, это противоречит трудовому соглашению с профсоюзом уборщиков мусора. 

Автор: COVD2 9.9.2006, 21:56
Вот нашел http://java.sun.com/docs/hotspot/gc1.4.2/faq.html:

31. Should I pool objects to help GC? Should I call System.gc() periodically? 

The answer to these is No!

Pooling objects will cause them to live longer than necessary. We strongly advise against object pools.

Don't call System.gc(). The system will make the determination of when it's appropriate to do garbage collection and generally has the information necessary to do a much better job of initiating a garbage collection. If you are having problems with the garbage collection (pause times or frequency), consider adjusting the size of the generations.



Автор: y3u 9.9.2006, 23:51
Цитата(COVD2 @  3.9.2006,  16:55 Найти цитируемый пост)
Да, для нормального приложения, которое ни в чем себе не отказывая плодит одноразовые обьекты, это не поможет. А постоянные обьекты (кэш) в некоторых случаях ведут себя вполне предсказуемо. И можно определенно сказать сколько надо памяти приложению в начале цикла (утром) и насколько она возрастет к вечеру. 


вообще, раз уж речь пошла о промышленном софте, то тут без профайлера не обойтись. Правда я бесплатных не знаю, точнее знаю только один http://www.ej-technologies.com/products/jprofiler/overview.html  smile  Весчь незаменимая именно в тех случаях, когда надо привести код к состоянию пониженного отжЫрания памяти и протса. 
имхо, проставление ссылок в null это, конечно, хорошо, но сильно отвлекает от процесса разработки. Обычно чтобы не шаманить таким образом нужно внимательно изучить код и посмотреть на области видимости переменных, чтобы они были как можно уже. Об этом хорошо написано у Дж. Блоха.

Автор: COVD2 12.9.2006, 16:09
Полезно также вывести в лог сообщения gc (опция -Xloggc: ). 

Цитата

имхо, проставление ссылок в null это, конечно, хорошо, но сильно отвлекает от процесса разработки. Обычно чтобы не шаманить таким образом нужно внимательно изучить код и посмотреть на области видимости переменных, чтобы они были как можно уже.
 

- т.е. идеально, чтобы все переменные были локальными. Тогда в каждом методе будут в изобилии создаваться и умирать новые локальные обьекты (если переменные не примитивные типы). Собственно , и Sun тоже не призывает экономить на обьектах.  Работать должна машина ( gc ), а не человек.  smile  


Автор: y3u 12.9.2006, 22:16
Цитата(COVD2 @  12.9.2006,  16:09 Найти цитируемый пост)
Тогда в каждом методе будут в изобилии создаваться и умирать новые локальные обьекты (если переменные не примитивные типы)


а в этом нет ничего плохого, эти переменные будут доступны при сборке сразу же, как только отработает метод, где у них кончается скоуп. Они-то, как раз, будут убраны гарантировано. А вот с подвисшими в памяти объектами которые не нужны, но вот по какой-нибудь потеряной ссылке все еще цепляющиеся за жизнь, разобраться куда сложнее, бывает и такое... Кстати, а в коммерческих JVM все должно быть в этом плане радужнее, мне тут говорили, что на джей роките скорость работы приложений и эффективность гарбадж коллектора примеро в 2 раза больше, чем у штатной джавамашины... Кто-нибудь может что-либо сказать по этому поводу? Интересно...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)