Tomcat 6 утечки памяти записей журнала - PullRequest
7 голосов
/ 04 февраля 2011

Ниже приведен список уникальных записей в моем файле Catalina.out на компьютере CentOS. Я использую Tomcat 6 с пружиной 3 и моим приложением. Их целая куча, поэтому я просто выбрал несколько, которые продолжают повторяться. Это не происходит все время, но происходит, по крайней мере, один раз в неделю.

Вопрос в том, что я могу сделать, чтобы предотвратить появление рева?

Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc

SEVERE: The web application [] registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

SEVERE: The web application [] appears to have started a thread named [com.iteezy.shared.domain.DirEntry.data] but has failed to stop it. This is very likely to create a memory leak.


Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [] appears to have started a thread named

[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0] but has failed to stop it. This is very likely to create a memory leak.


Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads  

SEVERE: The web application [] appears to have started a thread named [File Reaper] but has failed to stop it. This is very likely to create a memory leak.

Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

SEVERE: The web application [] appears to have started a thread named [pool-1-thread-22] but has failed to stop it. This is very likely to create a memory leak.  

37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
b application [] appears to have started a thread named 

[org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2] but has failed to stop it. This is very likely to create a memory leak.

37:48 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap

b application [] created a ThreadLocal with key of type [net.sf.json.AbstractJSON$1] (value [net.sf.json.AbstractJSON$1@40bbb3d6]) and a value of type [java.util.HashSet] (value [[]]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.

Ответы [ 3 ]

12 голосов
/ 27 октября 2011

Когда вы определяете внешний флаг, который поток должен опрашивать и завершать, когда он установлен - , он должен быть volatile.В противном случае поток может никогда не увидеть изменения, сделанные другим потоком.

Однако в стандартном API уже есть такая функция - она ​​называется методом interrupt() и Thread.currentThread().isInterrupted().Не нужно дублировать уже существующую логику.См .: Остановка определенного потока Java .

Сказанное, что вызов interrupt() для каждого потока также является плохой идеей, потому что нет гарантии, что все потоки ответят на него.Изучая ваши исключения, я заметил, что следующие потоки не очищаются должным образом:

  • com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0 - закрыть источник данных C3P0.Поскольку вы используете Spring, просто добавьте destroy-method="close".Мы закончили с этим потоком.

  • File Reaper - насколько я вижу, этот поток создан FileCleaningTracker .Вам необходимо явно вызвать FileCleaningTracker.exitWhenFinished() при закрытии приложения (или когда класс больше не нужен, я никогда не использовал его) или позволить Spring сделать это (см. Выше).Скорее всего, какая-то сторонняя библиотека использует ее и не закрывается должным образом - это означает, что в ней есть ошибка.

  • pool-1-thread-22 - это один из потоков, созданных Executors утилита внутри ExecutorService.Убедитесь, что вы вызываете shutdown() для каждого такого пула в приложении во время выключения.

  • org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 - Кварцевый рабочий поток (тот, который фактически выполняет задания).SchedulerFactoryBean автоматически закрывает для вас планировщик, я думаю, что Tomcat здесь ошибается, я также часто вижу эту ошибку.Тем не менее, похоже, что установка SchedulerFactoryBean.waitForJobsToCompleteOnShutdown в true решает эту проблему.

  • com.iteezy.shared.domain.DirEntry.data - Я не уверен в этом.Это либо ваш собственный поток, который необходимо прервать при завершении работы, либо поток базы данных H2 (?) Его стек необходимо проверить, чтобы определить, откуда он.

Суть в том, что: не просто уничтожайте все, что движется (на самом деле Tomcat делает это за вас после выдачи этого предупреждения), но и определяйте, откуда берутся потоки, и используйте специфичный для фреймворка / библиотеки метод close(), чтобы обеспечить дальнейшую очистку.Будь нежным.

1 голос
/ 04 февраля 2011

Настройте сервлет для управления этим методом destroy(). Потоки могут проверить флаг, чтобы увидеть, должны ли они продолжать или нет.

В вашем сервлете выполните следующее в методе уничтожения. Очевидно, вам нужно будет иметь доступ к Collection<MyThread>, но то, как вы его получите, зависит от того, как настроена ваша система.

destroy() {
    for (MyThread thread : myThreads) {
        thread.stopProcessing();
    }
}

Ваш класс MyThread будет выглядеть примерно так:

public class MyThread {
    private boolean finished = false;

    @Override
    public void run() {
        while (!finished) {
            //do something
        }
    }

    public void stopProcessing() {
        finished = true;
    }
}
0 голосов
/ 04 февраля 2011

Правильно завершите работу вашего веб-приложения. Не оставляйте эти темы запущенными.

В качестве альтернативы, не продолжайте повторно развертывать веб-приложение.

...