| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > виснет приложение после N запросов |
| Автор: 4epT 19.4.2011, 10:13 | ||||||||
| Доброе утро! Столкнулся с проблемой ... почему то приложение виснет после выполнения N операций подряд. Приведу пример: Есть страница с comboBox, в который грузятся страны:
По нажатию на кнопку удаляется выбранная страна:
Managedbean - countryController имеет область жизни Request. CountryDao - это спринг бин, который прописан в applicationContext:
BaseDaoImpl - это дженерик dao. И на последок, метод как я вытягиваю страну по имени:
Извиняюсь что описание получилось большое, попытался как можно понятнее описать структуру проекта. Подскажите где я мог ошибиться ? или подскажите как хоть это отлаживать ? Через дебагер все объекты не null, то есть все вроде нормально. Виснет примерно после 4 - 5 транзакциях. Заранее спасибо! |
| Автор: Vasay 19.4.2011, 12:50 |
| А что в логе? Памяти в системе достаточно для работы АПП сервера? |
| Автор: 4epT 19.4.2011, 12:57 | ||
В логах пусто, там видны только запросы к БД. Вот насчет памяти не знаю. Но ведь глупо когда приложение ложится при попытки удалить 4 страны ? К слову в таблице country всего 10-15 стран. Как можно увеличить объем доступной памяти ? может и вправду в этом дело. Очисткой памяти ведь должен заниматься GC ... и countryController должен полностью выгружаться из памяти так как у него время жизни Request ... Поправьте если не прав. |
| Автор: COVD 19.4.2011, 13:14 | ||
закрываете? |
| Автор: 4epT 19.4.2011, 13:27 | ||||||||
В hibernate конфиге указано:
или я не про то закрытие понял ? p.s. метод удаления из BaseDaoImpl:
|
| Автор: MisterCleric 19.4.2011, 14:01 |
| Hibernate тут не причем. Запускай профайлер и смотри, кто у тебя кушает память |
| Автор: 4epT 19.4.2011, 14:08 | ||
Слышал что в нетбинсе встроен профайлер ... где его там можно найти ? |
| Автор: Vasay 19.4.2011, 14:22 | ||||
4epT
А в логе APP сервера? Если с памятью проблема - должен на это выругаться.
в настройках апп сервера. Где-нибудь должны стоять ключи: Xmx/Xms . |
| Автор: 4epT 19.4.2011, 14:31 | ||||
под логами я имею ввиду вкладка netbeans - Apache Tomcat Logs (или как то так ...).
можно пример для томкета ?) где эти параметры прописать =) |
| Автор: Vasay 19.4.2011, 15:10 |
| Если под виндой - смотрите Catalina.bat, на предмет "set JAVA_OPTS = Xmx****m" Но я не уверен, что если Вы запускаете томкэт из нетбинса, то он не обходит Catalina.bat, запуская его со своими опциями. П.с. я не знаю насколько хорошо NetBeans дружит с TomCat, но если Вы запускаете приложение из NetBeans - попробуйте запустить его на GlassFish - там очень хорошо все отображается в IDE вплане ошибок. Будет сразу видно в чем проблема - памяти не хватает, или эксепшен в вашей программе какой... (хотя в логах томкэта это все тоже должно быть...) |
| Автор: 4epT 19.4.2011, 15:20 | ||
Как буду дома попробую ... ) всем спасибо за помощь! Как что то будет известно отпишусь ) |
| Автор: 4epT 19.4.2011, 20:02 | ||||
Попробовал поднять приложение на GlassFish. При старте сервера ошибок не было кроме WARNING:
К слову выше указанные ворнинги, не единственные. их там порядка 10-15, между собой похожи ... Может я не правильно настроил dataSource ? в спринг контексте ... Ну и вот такой эксепшен:
Profile запустить не получилось, вылетает ошибка и все ... ( сори, за такое форматирование ... не пойму почему так получается. |
| Автор: Vasay 19.4.2011, 20:32 |
| 4epT, А заработало несмотря на эксепшен или нет? Пс - система какая? Где установлен GlassFish (в какой папке)? Не баг ли это из-за того, что ему не дают создать файлы в програмс файл? |
| Автор: 4epT 19.4.2011, 23:17 | ||
Под GlassFish заработало, но не полностью ... из базы country вытянул, но не удаляет ... Система Windows 7=) GlassFish установлен в C:\Program files\glassfish И все таки хотелось бы на томкете подымать приложение .. ) |
| Автор: Vasay 20.4.2011, 01:01 | ||||
При попытки удаления должен тогда сыпать эксепшенами....
Наверно, с этим и связана ругань насчет невозможности создания папки. |
| Автор: 4epT 20.4.2011, 09:23 | ||||
В логах томкета увидел вот такое:
такое написало после удаления второй страны, потом метод jsf бина getAllCountry уже не смог прочитать страны:
Это не похоже на ошибку ?) |
| Автор: 4epT 20.4.2011, 20:59 | ||
Выяснил что приложение ложиться из за:
Смотрел через профайлер, когда доставал список стран было видно что очень сильно скакнула память ... памяти выделил 512 метров, каким образом так быстро память улетает ? Что с этим делать? |
| Автор: dobrolub 20.4.2011, 21:28 |
| permGen используется для кэширования классов (в числе прочего) и в если ошибки будут продолжатся и далее, то нужно посмотреть где текут класслоадеры (java.lang.Classloader и его наследники) для этого есть утилитка jmap, запускай её с ключом -permstat и смотри на результат. На винде она не работает с этим ключом к сож. jmap -permstat <pid> Добавлено через 5 минут и 23 секунды для винды, чтото вроде http://www.yourkit.com/docs/kb/class_loaders.jsp о |
| Автор: 4epT 20.4.2011, 22:36 | ||
| Установил YourKit, попытался разобраться .... но очень много показателей и просто напросто запутался. Можете подсказать куда конкретно посмотреть ? Или может быть просто увеличить permsize ? нашел во вкладке Class List:
есть еще один класс, объектов которого 51 ... но он не мой, он находится в пакете com.sun.org... ну и есть 118 799 - java.lang.String и примерно столько же char[] p.s. Как часто вообще сталкиваются с такими проблемами ? Не у одного знакомого такого не было... |
| Автор: dobrolub 20.4.2011, 22:56 |
| в моей практике было пару раз. Причиной может быть количество классов в аппликухе (включая библиотеки, конечно) требующее больший permgen чем выделяется по умолчанию, или, "ClassLoader leak" - когда классы загружаюся в новый класслоадер снова и снова, и ссылка на класслоадер остаётся. первое просто требует увеличения permgen, второе -баг в аппликухе и его надо найти и исправить. Добавлено через 2 минуты и 23 секунды Если после увеличения до 512м у тебя ошибки прекратяться, то всё в порядке. Если будут продолжать лезть - найди наиболее повторяющийся класслоадер (г. типа org.spring org.hibernate ) и следи, не растёт ли их число . |
| Автор: 4epT 20.4.2011, 23:01 |
| Не подскажешь как правильно увеличить permgen ? ) я через IDE (netbeans) полез в настройки сервера и прописал там параметр: -XX:MaxPermSize=512m |
| Автор: dobrolub 20.4.2011, 23:29 |
| catalina.bat декларирует несколько параметеров; твой - JAVA_OPTS нужно установить присвоить переменной окружения ( Environmеnt Variable ) значиение -XX:MaxPermSize=512m если запускаешь из коммандной строки сделай set JAVA_OPTS=-XX:MaxPermSize=512M catalina.bat start или установи её глобально, такоже как устанавливают JAVA_HOME, ANT_HOME, ORACLE_HOME и т.д. Ну и конечно убедись что она действительно встала с помощью jvisualvm или jconsole |
| Автор: 4epT 21.4.2011, 00:01 |
| dobrolub, увеличение permgen результата не дало ( какие самые распространенные баги в "аппликухе" ? Как выяснить где я напорол ? |
| Автор: dobrolub 21.4.2011, 00:09 |
| Ну вот перезагрузка веб-аппликухи такой эффект может дать. В томкат 7 есть даже такая фишка - протекция против permgen leak. http://wiki.apache.org/tomcat/MemoryLeakProtection Я думаю первый шаг - убедиться что ты на томкат 7, а потом анализировать дерево классов, смотреть что держит лоадеры которые растут в числе. Ешё погугли на предмет permgen и библиотек которые в твоей аппликухе крутятся. |
| Автор: 4epT 21.4.2011, 16:33 |
| скажите пожалуйста, а может ли быть проблема в неправильной конфигурации Spring / Hibernate ? P.s. просто в плане архитектуры у меня сомнения в том что я где то напорол ... так как весь дао списан с работы. Единственное что сам писал так это файлы конфига + вместо Struts подключил JSF ... |
| Автор: 4epT 21.4.2011, 23:22 | ||||
| Выяснил что метод getAllCountry за один сабмит вызывается три раза Оо. вот код страницы:
А вот managed jsf bean:
Как видно, я по "сабмиту" вызываю метод getAllCountry и потом перерисовываю панель. Каким образом метод вызывается 3 раза ? 2 раза вызывается - при нажатии на кнопку и один раз после удаления. |
| Автор: kaa 26.4.2011, 11:08 | ||
| 4epT, сам сейчас только вникаю в тонкости JSF, но в общем троекратный вызов метода связан с жизненным циклом запроса. Как только твой запрос пришёл на сервер, JSF пытается восстановить дерево страницы и провалидировать значения. После обработки он обновляет дерево страницы - и тоже запрашивает данные со всех бинов - глянь на код своей страницы. У тебя там есть запись
Соответственно, при восстановлении дерева страницы, JSF должен знать какая инфа может содержаться в данном компоненте и перед рендерингом, при обновлении дерева ему нужно получить актуальную инфу для селекта + в процессе валидации скорее всего дёргает проперти данного бина (не спрашивай почему, для меня пока это тоже тёмный лес). В общем кол-во вызовов функций, представляющих проперти бина, зависит от процесса обработки и компонента и может сильно разниться Вообще работая с БД в JSF без кеша лучше не жить - жрёт память как бегемот и тупит как ленивец. Добавлено @ 11:09 Попробуй в самом деле с хиберовскими кешами поиграться - может поможет? Добавлено @ 11:11 Особое внимание удели кешу второго уровня. Он там по умолчанию отключен. |
| Автор: 4epT 26.4.2011, 12:39 |
| Спасибо за ответ =) Я включил в настройках хибера использовать кеш второго уровня - это достаточно ? или лучше использовать специальные либы для кеша ? Ну и на сколько я понял трехкратный вызов метода никак не исправить ?) P.s. зависание больше не происходит ... исправил в baseDaoImpl метод - list. Сделал его @Transactional. |
| Автор: kaa 27.4.2011, 20:36 |
| Привет! По поводу кэша: что-то я не слышал про сторонние либы для кеширования кишков хибера. Да и странно это было бы. Хибер-то лучше знает что ему надо - это он рулит ентити-объектами. Про вызов: нет, это ядро JSF само дёргает, для своих нужд. Уточнить просто хочется: после добавления @Transactional виснуть перестало? |
| Автор: 4epT 28.4.2011, 00:08 |
| Да после добавления @Transactional виснуть перестало. И помойму я даже понял почему ... дело в том что висло при запросе select ... и видимо хибер делал не простой select а что то вроде select for update. И из за частого выполнения этого запроса ( из за JSF ) делался дед лок на базу и и за этого все висло. |
| Автор: kaa 28.4.2011, 09:43 |
| Хитро блин Спасибо, запомню на будущее |
| Автор: 4epT 28.4.2011, 10:39 |
| Не за что =) |