Текущий архив: 2006.02.05;
Скачать: CL | DM;
Вниз
Вопрос по Java Найти похожие ветки
← →
kaif © (2006-01-13 12:18) [0]Извиняюсь, что не по теме.
Пришлось тут написать один проект на Java.
Никак не могу привыкнуть к тому, что аллокированные ресурсы удаля ются не явно (как я привык в Delphi), а каким-то таинственным сборщиком мусора java-машины.
Я понимаю, что это не форум джавистов. Но это форум людей, привыкших заботиться о корректной работе с ресурсами (память, дескрипторы и т.п.).
Вопрос. Существуют ли, тем не менее, ситуации, когда java приводит к утечке ресурсов или я могу вообще об этом не задумываться и слепо полагаться на ее сборщик мусора? Если же существуют такие ситуации, то чего следует избегать?
Речь идет о сервлетных приложениях на java по Tomcat.
← →
Alex Konshin © (2006-01-13 12:24) [1]Существуют. Если считать, что JVM работает корректно, то ты сам можешь создать утечку. Например, завести какой-нибудь вектор как статическое поле в классе и постоянно добавлять туда что-нибудь и не удалять.
Объекты удаляются только если на них нет ссылок.
← →
Sandman29 © (2006-01-13 12:28) [2]Например, завести какой-нибудь вектор как статическое поле в классе и постоянно добавлять туда что-нибудь и не удалять.
Разве это утечка? Это глобальная переменная, к которой можн обратиться.
← →
Esu © (2006-01-13 12:31) [3]Нужно следить за ссылками. Неявными рекурсиями и тд.
← →
Ломброзо © (2006-01-13 12:33) [4]> завести какой-нибудь вектор как статическое поле в классе и постоянно добавлять туда что-нибудь и не удалять.
Да, кроме того, часто встречаются циклические ссылки - первый объект ссылается на второй, второй - на первый. Вообще аналогом деструктора в Java является метод Object.finalize()
← →
Ломброзо © (2006-01-13 12:45) [5]Уточнение: на finalize() полагаться, впрочем, не стоит, поскольку этот метод дёргается Garbage Collector-ом, а когда этот метод вызовется - никому не известно. Поэтому я бы посоветовал для класса, который хапает какие-то ресурсы, реализовать метод, форсирующий чистку памяти: например, для класса, инкапсулирующего работу с файлом - метод close(), для класса, работающего с базой данных - метод disconnect(), для всех остальных - ну, к примеру, destroy()
← →
iZEN © (2006-01-13 12:45) [6]Ломброзо © (13.01.06 12:33) [4]
С циклическими ссылками в Java научились бороться в каком-то седом году конца XX века. Если на кольцо или другую самозамыкаемую структуру ссылок нет внешней ссылки, то такие ссылки удаляются сборщиком мусора.
Вообще-то, прежде чем делать какие-либо умозаключения насчёт утечек памяти в Java, полезно почитать "Горький вкус Java" Брюса Тейта и "Типичные ошибки проектирования" Эрика Аллена.
← →
Ломброзо © (2006-01-13 12:50) [7]> С циклическими ссылками в Java
Я знаю ) я немного не тот пример привёл: пусть, к примеру, у меня есть класс A, содержащий экземпляр ArrayList, каждый элемент которого содержит ссылку на экземпляр класса B, который, в свою очередь, ссылается на A. Это тоже разновидность циклической ссылки, с которой GC в JDK 1.3 не справлялся.
← →
kaif © (2006-01-13 13:42) [8]К примеру, имеется некий сервлет или jsp, которое tomcat превращает в сервлет и загружает. Этот сервлет есть наследник класса сервлетов, предназначенных для обслуживания HTTP-запросов. Заведует всем этим делом контейнер сервлетов (у меня tomcat 5.5). Допустим я создаю некий ArrayList и ссылку на него храню в атрибуте сессии "сервлетного приложения". Сессию tomcat сам закрывает по истечении какого-то времени, скажем, пол-часа, если юзер не обращается к серверу. Сессия обслуживается неким ID, который сервер сам пишет в cookie юзера. С сессией связана хеш-таблица, в которой экземпляр сервлета хранит атрибуты в виде пар "ключ,значение." (так устроен сам класс сервлетов) Так вот я и записываю в эту хеш-таблицу ссылку на мой экземпляр ArrayList, который хранит ссылки на экземпляры каких-то моих классов. Таким образом у каждого юзера будет свой ArrayList в контексте его сессии. Могу ли я быть уверенным, что tomcat (или джава-машина) гарантированно удалят экземпляр ArrayList-а и все экземпляры моих классов, ссылки на которые содержатся в ArrayList после того, как сессия закроется? Циклических ссылок нет. Есть просто "длинные ссылки" (они мне интуитивно кажутся "длинными", я ничего в это слово не вкладываю, кроме ощущения и потому прошу ногами не бить). Как-то все это очень стремно... Возможно я просто пока не привык. Странно, что это довольно шустро работает. Я ожидал намного худшей картины. Не верится, что джава-машина всеми существующими ссылками и всегда вовремя убирать мусор...
← →
kaif © (2006-01-13 13:45) [9]Пропустил слово:
Не верится, что джава-машина успевает следить всеми существующими ссылками и всегда вовремя убирать мусор...
Она их что, постоянно сканирует, что ли?
Но тогда это не могло бы быстро работать...
Видно там какая-то гениальная идея реализована, о которой я не знаю.
Или же она просто убирает мусор периодически, подвешивая при этом все остальное.
← →
Игорь Шевченко © (2006-01-13 14:00) [10]
> Не верится, что джава-машина успевает следить всеми существующими
> ссылками и всегда вовремя убирать мусор...
Наверняка какой-нибудь отложенный алгоритм, как в .Net.
Про .Net можно прочитать в http://rsdn.ru/article/dotnet/GCnet.xml
← →
Ломброзо © (2006-01-13 14:05) [11]Высказываю ИМХО, если что, меня поправят )
> гарантированно
Да, гарантированно.
> постоянно сканирует
Да, в отдельном потоке
> гениальная идея реализована
Просто определяет "удачный момент". Подробностей алгоритмов не знаю, но очевидно, что поток GC работает тогда, когда другие потоки обладают меньшим приоритетом, или занимают меньше процессорного времени и т.п.
Что касается собственно веб-приложений - не рекомендуется привязывать к сессии большие массивы данных, хранимые в сессии в течение её жизни. То есть из двух альтернатив:
1) получить из Cookie какой-то идентификатор, получить какие-то данные, закэшировать их в сессии и полагаться на сборку мусора и
2) получить из Cookie идентификатор, получить данные, уничтожить данные
при разработке интернет-порталов с предпочтителен второй вариант, но для интранет-решений с количеством пользователей 10-50 приемлем и первый.
← →
kaif © (2006-01-13 16:31) [12]2 Ломброзо © (13.01.06 14:05) [11]
Понял, спасибо.
То есть на уборку мусора в общем-то можно положиться.
У меня небольшое интранет приложение со сложным анализом данных из ORACLE. Просто мне иногда нужно бывает запоминать в пределах сессии небольшие массивы (не более десятков элементов), в основном ради кеширования некоторых метаданных при динамическом построении текстов SQL-запросов, чтобы не запрашивать каждый раз все нужные структуры метаданных из базы.
Просто у меня происходят странные сбои компьютера (перезагрузка) и я стал грешить на уборку мусора, многопоточность и т.п. Хотя скорее всего у меня просто что-то с памятью происходит или с диском, так как на другом компьютере вроде программа нормально работает и сбоев ни разу не наблюдалось... Сбои явно происходят после долгой работы с tomcat при очередном клике на какой нибудь невинной ссылке в браузере.
Страницы: 1 вся ветка
Текущий архив: 2006.02.05;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.012 c