| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Tomcat: утечка памяти в Heap Space |
| Автор: Stampede 10.12.2008, 00:20 |
| Имеется такой неприятный глючок: вебсайт на Томкате периодически вычерпывает всю память, начинает выкидывать OutOfMemoryError, а потом и вовсе становится колом. Приходится перезапукскать. Самое смешное, что когда я нагружаю вебсайт "нагрузчиком", он прекрасно справляется и держит нагрузку как стойкий оловянный солдатик. У меня даже JCrawler сломался на пятой тысяче запросов, а сайту хоть бы хны. Между тем в реале сайт зависает пару раз в день, причем от рестарта до зависания происходит всего лишь пара сотен обращений к серверу (к динамической его части, где генерится контент). С учетом всего сказанного, у меня возникло предположение, что дело, скорее всего, в какой-то побочной функциональности: может, в статике, может, браузерный mp3-плейер не отпускает открытый файл, а может где-то треды бегают и держат свои ресурсы. Вопрос: как вычислить виновника, учитывая, что дело происходит на уделенном сервере, доступ к которому только через терминал (SSH) и FTP. ЗЫ. Профайлером на локальном компе смотрел, никакой утечки не обнаружил. |
| Автор: necromancer 10.12.2008, 12:01 |
| Может много памяти кушают пользовательские сессии? Ты когда нагружаешь нагрузкой пересоздаешь сессии или конектишься к одной и той же. |
| Автор: Maksym 10.12.2008, 12:14 |
| Stampede Можно сделать memory dump, забрать его и посмотреть HeapAnalizer'ом. Добавлено через 40 секунд правильное название HeapAnalyzer |
| Автор: Shurr 11.12.2008, 11:33 |
| Stampede А в какой области памяти падает OutOfMemoryError? Полный стектрейс не покажешь? |
| Автор: Shurr 11.12.2008, 12:32 |
| Stampede Попробуй включить лог сборки мусора, возможно он поможет выявить утечку. |
| Автор: Maksym 11.12.2008, 14:07 | ||||
Stampede
Там должно быть довольно четко видно кто сколько схавал..
А Velocity нигде http://www.nabble.com/out-of-memory--heap-overflow-after-many-VelocityEngin.init-calls-td13514959.html такими вещами. |
| Автор: Stampede 18.12.2008, 11:06 |
| Все, эпопея завершена. Глюк пофиксен. Подробности - http://real-english.ru/blog/memory-leak-fixed.htm. ЗЫ: Maksym получает плюса за подталкивание изучения вопроса в правильном направлении. necromancer - за привлечение внимания к интересному аспекту нагрузочного тестирования. ЗЗЫ: Всем остальным - спасибо за внимание! |
| Автор: Kangaroo 18.12.2008, 11:12 | ||
А можно посмотреть на эту выстраданную строчку? |
| Автор: Asal 18.12.2008, 11:19 |
Поздравляю ! Вот только вопрос: поделиться той строчкой кода, которая все решила, можешь ? И где можно глянуть на Breeze, интересно стало |
| Автор: Maksym 18.12.2008, 15:23 |
| Stampede Memory Analysis - вещь. |
| Автор: Asal 18.12.2008, 15:30 |
у меня эта вещь не запустилась, при 2 гигах оперативы, ругнулась: "Не могу выделить нужное количество памяти" |
| Автор: COVD 18.12.2008, 23:41 | ||||
И чей же это "глюк". Неужели Томката?
|
| Автор: Kangaroo 18.12.2008, 23:55 | ||
Есть надежда, что сейчас мы получим долгожданный ответ |
| Автор: Stampede 19.12.2008, 00:46 |
Есть такая буква - http://real-english.ru/blog/memory-leak-fixed.htm Добавлено: куча подробностей, скриншоты, сниппеты, раздел "благодарности". Там же ответы на все вопросы, которые поднимались в обсуждении. Давай мыло, что-нибудь придумаем. Вполне мог быть и Томката. Такое в истории http://www.google.com/search?q=tomcat+memory+leak. И потом, я разве что-то говорил, что грешу именно на него? Упоминание Томката в заголовке имело целью всего лишь обозначить место действия. А если язвительное "чей же это "глюк"" - это все, что ты вынес из этой истории, то даже не знаю, что и сказать. Всем остальным - еще раз спасибо за участие! |
| Автор: COVD 19.12.2008, 06:46 | ||
|
| Автор: Stampede 19.12.2008, 08:10 |
Ах, вот оно как оказывается Знаешь, COVD, этот случай подтвердил мою давнишнюю теорию, что большинство конфликтов порождаются элементарным недопониманием, кто чего имел в виду. Ну хорошо, я рад, что все разрешилось без мордобития и эскалации напряженности. Каковой факт я отчасти ставлю в заслугу самому себе: много слов крутилось у меня на языке, но я выбрал самые нейтральные Теперь по сути. Томкат в данном случае действительно ни при чем. Это чисто мой программистский недосмотр: необнуление переменной в момент, когда она перестает быть нужна. Но и большого криминала там с моей стороны тоже нет: поскольку ThreadLocal данного типа привязан к потоку под фиксированным именем, накопления связанной пямяти через этот механизм не происходит - при каждом новом запросе вместо старой инфы прописывается новая, а старая освобждается для сбора мусорщиком. Именно поэтому я не только не мог отловить это дело профайлером, но мне даже не удавалось завалить сервер нагрузчиком! Резюмируя историю в целом: от ошибок не застрахован никто. Как известно, не ошибается тот, кто ничего не делает. Важно не бояться признаться в своих ошибках, быть готовым ликвидировать их последствия, и извлекать уроки на будущее. Я могу сказать, что я вышел из этой ситуации более сильным, чем когда в нее входил. Я получил навыки борьбы с ликами, пополнил свой арсенал полезными прогами, подчистил многие места в конфигах, обновил кучу библиотек. Если я в будущем снова столкнусь с проблемами утечки памяти, я буду готов к борьбе с ними гораздо лучше. Так что трепещите, мемори лики - я вас больше не боюсь! Ну и надеюсь, мой опыт окажется в чем-то полезным и для вас. Не всем же учиться строго на собственных ошибках |
| Автор: ivg 19.12.2008, 11:11 | ||
Позволю себе сделать небольшое дополнение по теме. По моему скромному разумению лучше делать так:
Ну то есть идея понятна - не обнулять/удалять контекст из ThreadLocal, а возвращать старое значение перед возвратом управления контейнеру. Это нужно во избежании потери нашего контекста, например при использовании RequestDispatcher. |
| Автор: Stampede 19.12.2008, 11:55 | ||
На первый взгляд выглядит разумно: действительно, ведь могут существовать компоненты, которые сидят выше в цепочке вызовов и при этом используют конструкции фреймворка - например, какие-нибудь фильтры. Однако если продолжать размышлять в этом направлении, то вместо того, чтобы сохранять потенциально возможный предыдущий контекст таким "стековым" способом, возможно, лучше было бы дать компонентам из разных слоев возможность обмениваться инфой друг с другом - например, через механизм вложенных контекстов или что-то типа того. В общем, надо подумать. А вообще в архитектуре Бриза контроллер - это фактически точка входа во фреймворк (как он видится со стороны запроса), и RequestDispatcher отрабатывает уже внутри него, так что до сих пор проблем с потерей контекста не возникало. |
| Автор: necromancer 19.12.2008, 15:12 |
| to Stampede: а вы не хотели бы выложить исходники велкикого и ужастного breeze? |
| Автор: ivg 19.12.2008, 20:16 | ||||||
На всякий случай запощу пример потери контекста, о которой я говорил:
web.xml:
|