Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Утечка памяти Tomcat 6.0.16 + SSL


Автор: danilkus 30.4.2008, 14:00
Привет всем!

Запускаю на томкате простой сервлет.
Вот часть его кода:
Код

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().write("post!!!");
            response.setStatus(200);
      }


Используется чистый дистриб томката, скаченный с сайта. Конфиг используется стандартный, за исключением коннектора
Код

<Connector port="8443"
        maxHttpHeaderSize="8192"
        connectionTimeout="60000"
        enableLookups="false"
        disableUploadTimeout="true"

        maxThreads="900"
        minSpareThreads="350"
        maxSpareThreads="700"
        acceptCount="700"

        protocol="HTTP/1.1"
        SSLEnabled="true"
        scheme="https"
        secure="true"
        clientAuth="false"
        sslProtocol="TLS"
        keystoreFile="/opt/.keystore"
        keystorePass="tomcat" />


Система работает под нагрузкой следующего рода. 40 потоков, каждый из которых шлет раз в секунду POST запрос.
Никаких необычных заголовков в запросе нет.
Томкату при старте выдаю 300Мб памяти.

После примерно трех часов работы он выдает OutOfMemoryError.

Анализ дампа показывает подозрительно большое количество инстансов com.sun.net.ssl.internal.ssl.SSLSessionImpl. Остальное вроде все в норме.

Автор: Maksym 30.4.2008, 14:38
danilkus
На сколько помню у Tomcat дефолтное время жизни сессии 30 минут. Если каждый запрос порождает новую сессию (открывает новое соединение) каждую секунду, то память вполне может закончится. Запусти Tomcat с ключем -verbose:gc и понаблюдай как будет расходоваться и очищатся память во время теста.

Автор: danilkus 30.4.2008, 15:49
Пробовал ставить keepAliveTimeout в 0. По идее после этого сокет должен закрываться сразу после отправки ответа и HTTP сессия соответственно. Не помогло.

Во тут описывается точь в точь такая же проблема.
http://forum.java.sun.com/thread.jspa?threadID=5266266&tstart=0
Судя по всему проблема в реализации JSSE.

Можно ли как-нибудь запустить томкат с другим провайдером SSL? Если кто-нибудь пробовал подскажите примерно как это делается.

Автор: Maksym 30.4.2008, 16:10
Цитата(danilkus @  30.4.2008,  14:49 Найти цитируемый пост)
Пробовал ставить keepAliveTimeout в 0.

Где? Попробуй в web.xml именно твоего приложения поставить короткий таймаут сессии. 
Цитата(danilkus @  30.4.2008,  14:49 Найти цитируемый пост)
По идее после этого сокет должен закрываться сразу после отправки ответа и HTTP сессия соответственно. Не помогло.

Не факт, что сервлет контенер убивает сессионый объект сразу же. Скорее всего нет.


И все таки попробуй -verbose:gc, он же всю картину показывает.



Автор: danilkus 30.4.2008, 16:29
Цитата

Где?

в настройке томкат коннектора, через который идут все запросы.

Цитата

Попробуй в web.xml именно твоего приложения поставить короткий таймаут сессии.

попробую

Цитата

Не факт, что сервлет контенер убивает сессионый объект сразу же. Скорее всего нет.

ну а смысл держать объект если сокет закрыт. Все равно будут только новые сессии.

Цитата

И все таки попробуй -verbose:gc, он же всю картину показывает.

мониторил через JConsole. Видно что каждый раз fullGC освобождает меньше объектов из пула постоянных объектов  heap. И соответственно работать ему приходится все чаще. По дампу видно что есть куча инстансов SSLSessionImpl, которые держатся ссылками из Finalizer и именно их GC и не может подчистить. Больше ИМХО там увидеть ничего нельзя.

Автор: Maksym 30.4.2008, 16:56
Цитата(danilkus @  30.4.2008,  15:29 Найти цитируемый пост)
Больше ИМХО там увидеть ничего нельзя. 

Согласен.

Цитата(danilkus @  30.4.2008,  15:29 Найти цитируемый пост)

ну а смысл держать объект если сокет закрыт. Все равно будут только новые сессии.

Может кривая реализация.

http://forum.java.sun.com/thread.jspa?threadID=5265860&tstart=120 тоже поднимается эта проблема. Без ответа.


Автор: danilkus 4.5.2008, 10:19
Как можно заставить томкат работать по SSL без JSSE?

Автор: Alexandr87 4.5.2008, 11:38
danilkus, можно поставить перед томкатом SSL акселератор. или какой-нибудь софт со схожими функциями.

Добавлено @ 11:42
А вообще надо будет посмотреть, может и возможно настроить Tomcat работать со сторонними реализациями JSSE. Мне кажется такое должно быть возможно.

Добавлено @ 11:51
PS. Кстати на сколько я помню, можно наладить взаимодействие между Apache (не Tomcat) серваком и Tomcat ом, чтобы Apache скармливал Tomcat у, обработку сервлетов и прочей java лабуды. Тогда SSL сервер можно будет поднять на Apache (не Tomcat) сервере, а запросы обрабатывать на Tomcat`е

Автор: Alexandr87 4.5.2008, 11:58
Можно подрубить openSSL
http://tomcat.apache.org/tomcat-6.0-doc/apr.html

Автор: danilkus 4.5.2008, 12:08
Цитата

Можно подрубить openSSL
http://tomcat.apache.org/tomcat-6.0-doc/apr.html


Этот вариант как раз пробую сейчас 

Автор: COVD 4.5.2008, 19:56
Когда визард нетбинса генерирует шаблон сервлета, то он дает такой код:

Код

PrintWriter out = reponse.getWriter();
try{
  out.println("...");
finally {
  out.close();
}


Может, вы не закрываете?

Автор: danilkus 5.5.2008, 09:36
Цитата

Может, вы не закрываете?


setStatus очищает буфер, поэтому там ничего копиться не может. Ссылка на out тоже помирает после ответа.
Тем более что если бы текло здесь проблема бы воспроизводилась и без SSL, а она не воспроизводится.
Хотя согласен, что такой код лучше.

Автор: danilkus 5.5.2008, 10:26
Цитата

Можно подрубить openSSL
http://tomcat.apache.org/tomcat-6.0-doc/apr.html


Если просто настроить использование openSSL, как указано http://tomcat.apache.org/tomcat-6.0-doc/apr.html, все равно используются классы JSSE и ситуация повторяется.

Автор: COVD 5.5.2008, 16:36
Цитата

setStatus очищает буфер, поэтому там ничего копиться не может


setStatus не замена out.close(), т.е. не закрывает стрим и не освобождает ресурсы. Можно выполнить setStatus, а потом продолжать с успехом писать в out, что невозможно после выполнения close().    

Автор: danilkus 5.5.2008, 16:50
Цитата

setStatus не замена out.close(), т.е. не закрывает стрим и не освобождает ресурсы. Можно выполнить setStatus, а потом продолжать с успехом писать в out, что невозможно после выполнения close(). 


Согласен, дырка определенная тут есть. Но проблема топика к сожалению не в этом.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)