Ключевые слова:tocat, java, memory, hibernate, (найти похожие документы)
From: Anton Melehin
Date: Mon, 3 Aug 2010 17:02:14 +0000 (UTC)
Subject: Поиск утечек памяти (memory leaks) в Tomcat 5
Оригинал: http://www.theserverside.ru/blog/2009/04/07/1239092580000.html
На боевом сервере неожиданно начались проблемы с памятью, дольше часа
экземпляр томката не выдерживал и глухо зависал.
Пришлось разбираться комплексно со всей системой.
1. Самое обидное, что модуль mod_jk метил экземпляр томката как
нерабочий, переходил к другому экземпляру и весил его тоже.
Обновление Mod_jk никакой пользы не принесло, экзмепляры продолжали
зависать. Чтобы исключить теоретические проблемы с mod_jk
mod_jk был заменён на mod_proxy с прямым обращением к серверному http
коннектору.
В httpd.conf вместо JkMount использована директива ProxyPass:
ProxyPass /prov/ http://127.0.0.1:8580/prov/
ProxyPassReverse /prov/ http://127.0.0.1:8580/prov/
В tomcat/conf/server.xml доработаны коннекторы для http:
<Connector port="8580" maxHttpHeaderSize="8192"
maxThreads="200" minSpareThreads="4" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
maxPostSize="20971520"
connectionTimeout="10000" disableUploadTimeout="false"
maxKeepAliveRequests="30"
/>
2.Далее началась возня только с tomcat. Для диагностики состояния
сервера рекомендую использовать веб-приложение TomcatProbe.
Основные показатели сервера выводятся замечательно.
С его помощью можно определить проблемы:
- С зависшими коннекторами - если вдруг они не отпускаются по нескольку часов.
- С утечками памяти. На графиках видно что происходит с памятью. Если
график с течением времени не усредняется на одном уровне - значит есть
проблемные приложения.
Для качественной диагностики желательно скачать и установить последнюю
версию JDK 1.6. http://java.sun.com/javase/downloads/index.jsp
Чтобы иметь возможность диагностировать состояние памяти, в catalina.sh
необходимо прописать ключ -Dcom.sun.management.jmxremote.
Ниже пример настройки для боевого сервера с Jboss:
JAVA_OPTS="-server -XX:MaxPermSize=64m -Dfile.encoding=Cp1251
-Djava.awt.headless=true
-Djava.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
-Djava.naming.provider.url=jnp://127.0.0.1:1199
-Djava.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
-Dconfigure_logging=true -Xms64m -Xmx768m
-Dcom.sun.management.jmxremote"
3.Диагностика утечек памяти. После наблюдения за сервером через
tomcatprobe стало очевидным что какое-то приложение поглащает память и
не желает её отпускать.
Для начала был создан новый экземпляр tomcat на который перенаправлена
работа с новыми приложениями. Разделение старых приложений и новых
позволило независимо мониторить два экземпляра tomcat и выявить
проблемное приложение.
Для диагностики утечек в JDK 6 появилось множество чудеснейших утилит:
- jmap. Позволяет увидеть состояние памяти и сделать дамп загруженных
объектов и их ссылок.
- jhat. Отличная утилита, которая работает с дампом и позволяет через
удобный http интерфейс его просмотреть.
Для начала необходимо выяснить какой pid у вашего приложения (далее
речь идёт о linux). С этой задачей легко справляется команда jps - она
демонстрирует pid всех запущенных java-приложений.
Выбираем необходимый нам пид и создаём дамп:
jmap -dump:format=b,file=/tmp/13517.dmp 13517
После этого запускаем сервер jhat:
jhat /tmp/13517.dmp
Теперь мы имеем всю информацию о загруженных классах по адресу: http://servername:7000/
Смотрим какой класс больше всех создан:
lynx http://servername:7000/showInstanceCounts/
вероятнее всего именно он держит память приложения. Щёлкнув по названию
класса получаем подробнейшее описание кто и как держит этот объект.
4. Шаманства с дампами памяти позволили выявить проблемные библиотеки -
hibernate 3 содержал ошибку связанную с неправильным использованием cglib.
Следующей точкой утечки оказалась старая библиотека ehcache. И
последней каплей, забивавшей память, оказалась настройка в ehcache.xml
указывавшая на хранение кэша некоторых объектов в течение 24 часов.
В результате все проблемные библиотеки были заменены на более свежие
стабильные версии.
5. К сведению: Ещё одна удобная утилита, которая более уместна при
локальной разработке или при возможности доступа к серверу через vnc
(или X server) - https://visualvm.dev.java.net/
Утилита подойдёт любителям графических интерфейсов. Очень наглядно
представлены все графики и разбор дампов.
На этом танцы с дампами прекратились, до новых времён, до следующих
ошибок :)