Catalina.out Ошибка утечки памяти - PullRequest
4 голосов
/ 30 декабря 2011

Я все еще вижу эту ошибку в tomcat/logs/catalina.out.

Dec 29, 2011 4:04:36 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/LoggingMonitor] appears to have started a thread named [Timer-1] but has failed to stop it. This is very likely to create a memory leak.
Dec 29, 2011 4:04:36 PM org.apache.coyote.http11.Http11Protocol destroy
INFO: Stopping Coyote HTTP/1.1 on http-8180

Стоит ли обдумывать, и если да, то как я могу исправить это?

Ответы [ 2 ]

3 голосов
/ 30 декабря 2011

Это, вероятно, не страшно (просто убить -9 или что-то) и достаточно легко исправить.Просто выясните, какое веб-приложение работает в контексте / LoggingMonitor, затем найдите его кодовую базу для ...

new Timer();

... и замените их все на ...

new Timer( true );

java.util.Timer по умолчанию не запускается в потоках демонов.В ваших веб-приложениях вам нужны таймеры для работы в потоках демона (иначе контейнер не сможет правильно завершить работу, так как ожидает завершения потока таймера, чего он никогда не делает).Найдите все вызовы "new Timer ()" и замените их на "new Timer (true)", и жалоба на ведение журнала должна прекратиться.

Потратьте некоторое время в JavaDocs, чтобы узнать что-нибудь о daemon vs non daemon Threads: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html

Когда я работаю в веб-приложениях, я всегда использую потоки демона, если в конечном итоге я выполняю какую-либо собственную многопоточность.Со средствами в java.util.concurrent это становится очень редким (приходится делать свои собственные потоки).

Наконец, и для записи, я ненавижу java.util.Timer и всегда рекомендую использовать что-токак ScheduledExecutor для выполнения периодических повторяющихся задачСлишком легко завязать таймер и извлечь протектор, на котором он выполняется, демон или иное.

2 голосов
/ 28 апреля 2014

Это сообщение не имеет большого значения , если , вы всегда останавливаете Tomcat, когда вы удаляете / повторно развертываете свое приложение, в противном случае эти операции вызывают утечку памяти, которая является большой проблемой, особенно на производстве.

Потоки с именем "Timer- #" создаются java.util.Timer (и, возможно, другими классами) в соответствии с предложением Bob Kuhar , но поиска собственной кодовой базы может быть недостаточно, иобеспечение того, что вы используете потоки демона, не устраняет это сообщение (комментарий Тома Хоутина верен).

Когда я получил это сообщение, оно было создано транзитивной зависимостью моего кода, точно классом GenericObjectPoolApache Commons Pool v1.3, использующий поток daemon (см. исходный код ).Чтобы найти класс, который создает экземпляр Timer, мне нужно было установить точку прерывания в конструкторе каждого класса Timer, а затем я исследовал стек вызовов.Чтобы решить эту проблему, мне пришлось обновить библиотеку (более новые версии Commons Pool не используют этот таймер).

Когда вы контролируете код, который создает поток, вы можете решить эту проблему, гарантируя, что выостановить поток, когда приложение останавливается.Использование потоков демонов является хорошей практикой, но этого недостаточно, поскольку потоки демонов умирают автоматически только при завершении работы Tomcat, но не при удалении приложения.

В более общем случае, когда вы не знаете, кто создалпротивный поток, отметьте Поиск источника создания потока в приложении Java и Определите, кто создал поток (w. Eclipse) .

ОБНОВЛЕНИЕ

Совершенно другой подход заключается в использовании очень интересного Прослушивающего устройства для предотвращения утечек .Также прочитайте другие посты об утечках из загрузчика классов этим автором.

...