Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > 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 | ||
Можно так же ускорить вызов коллектора(но не гарантировать что сейчас же ) строчкой:
|
Автор: Tony 1.9.2006, 11:35 | ||
Может код кривой? |
Автор: Lerm 1.9.2006, 23:46 | ||||
Только лучше всё таки так не делать - не стоит явно вмешиваться в работу GC. Это может потребоваться только в очень ограниченном количестве случаев. Появление проблем с памятью в большинстве случаев говорит о том, что либо имеется её утечка (копим неиспользуемые объекты), либо памяти просто выделено недостаточно (не рассчитали нужный объем, необходимый для хранения всех требуемых объектов). Кстати, я в первый раз слышу про такой Exception - JavaHeapSpaceException. Какой точно Exception выскакивает - OutOfMemoryError или что-то другое? На Unix-системах иногда вылетает Exception c not enough space при попытке вызвать сторонний процесс (fork не может память зарезервировать). А иногда (это особенно характерно для серверов приложений) OutOfMemoryError может свидетельствовать не о недостатке кучи, а нехватки Permanent-области. Так что без дополнительных сведений о приложении и том, как оно работает с памятью - сказать что-нибудь по проблеме сложно. |
Автор: COVD2 2.9.2006, 17:12 | ||
Java широко используется в серверных приложениях. Серверные приложения работают как правило круглосуточно. Причем активность пользователей может носить периодический характер. Например, максимум запросов днем и минимум - ночью. В этой ситуации естественно хочется явно запускать коллектор, чтобы в периоды простоя он почистил память, на всякий случай, чтобы в периоды активности ему меньше работы было. Однако явно управлять уборщиком мусора нельзя. Можно только "порекомендовать" ему заняться делом в виде многократных вызовов System.gc(). Одной из стратегий в данной ситуации является аккуратное программирование - по возможности "не мусорить". Не создавать без особой нужды новые обьекты, использовать пулы. Однако это идет в разрез с концепцией обьектно-ориентированного программирования. Как и любой другой тюнинг, это повышает эффективность, но делает программу более сложной. В то же время в последних версиях java уборка мусора может реализовываться в фоновом режиме, что менее болезненно для приложения. |
Автор: Lerm 3.9.2006, 11:27 | ||||
Ну, для нормального серверного приложения одно выполнение FullGC ночью вероятно ничего не даст - в течение дня он будет вызван не один раз. Я вижу применение вызова System.gc() только в тестовых и отладочных целях - когда мы хотим, скажем, замерить потребление памяти при выполнении некоторой операции.
Смотря для какого приложения. Для интерактивного приложения, которое должно всегда отзываться на действия пользователя - вероятно да, более полезно. Для серверных приложений, которые обрабатывают поток запросов, это хуже - проще в какой-то момент прерваться, бросить все силы на сборку мусора, а затем вернуться к работе - сумарная пропускная способность окажется выше. |
Автор: COVD2 3.9.2006, 16:55 | ||||
Да, для нормального приложения, которое ни в чем себе не отказывая плодит одноразовые обьекты, это не поможет. А постоянные обьекты (кэш) в некоторых случаях ведут себя вполне предсказуемо. И можно определенно сказать сколько надо памяти приложению в начале цикла (утром) и насколько она возрастет к вечеру. ...
Вот вы прерветесь, а входящие запросы придется в буфер класть, и буфер переполнится, и запросы потеряются. ![]() И все же жаль, что нет в 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 | ||
вообще, раз уж речь пошла о промышленном софте, то тут без профайлера не обойтись. Правда я бесплатных не знаю, точнее знаю только один http://www.ej-technologies.com/products/jprofiler/overview.html ![]() имхо, проставление ссылок в null это, конечно, хорошо, но сильно отвлекает от процесса разработки. Обычно чтобы не шаманить таким образом нужно внимательно изучить код и посмотреть на области видимости переменных, чтобы они были как можно уже. Об этом хорошо написано у Дж. Блоха. |
Автор: COVD2 12.9.2006, 16:09 | ||
Полезно также вывести в лог сообщения gc (опция -Xloggc: ).
- т.е. идеально, чтобы все переменные были локальными. Тогда в каждом методе будут в изобилии создаваться и умирать новые локальные обьекты (если переменные не примитивные типы). Собственно , и Sun тоже не призывает экономить на обьектах. Работать должна машина ( gc ), а не человек. ![]() |
Автор: y3u 12.9.2006, 22:16 | ||
а в этом нет ничего плохого, эти переменные будут доступны при сборке сразу же, как только отработает метод, где у них кончается скоуп. Они-то, как раз, будут убраны гарантировано. А вот с подвисшими в памяти объектами которые не нужны, но вот по какой-нибудь потеряной ссылке все еще цепляющиеся за жизнь, разобраться куда сложнее, бывает и такое... Кстати, а в коммерческих JVM все должно быть в этом плане радужнее, мне тут говорили, что на джей роките скорость работы приложений и эффективность гарбадж коллектора примеро в 2 раза больше, чем у штатной джавамашины... Кто-нибудь может что-либо сказать по этому поводу? Интересно... |