Проблема утечки памяти Tomcat в потоке log4j2

Я использую log4j2 для ведения журнала, версии tomcat8 и java8. Я использовал атрибут «monitorInterval» для периодической проверки файла log4j2.xml. Во время выключения моего кота я столкнулся с проблемой утечки памяти. Как решить эту проблему с утечкой памяти?

Ниже приведены журналы каталины:

06 октября 2016 г. 15:13:55.927 ПРЕДУПРЕЖДЕНИЕ [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Похоже, веб-приложение [mywebapp] запустило поток с именем [Log4j2-Log4j2Scheduled-1], но не удалось остановить его. Это очень вероятно, чтобы создать утечку памяти. Трассировка стека потока: sun.misc.Unsafe.park(собственный метод) java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer. java:2078) java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) java.util.concurrent.ThreadPoolExecutor.getTask( ThreadPoolExecutor.java:1067) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) java.lang.Thread.run(Thread. ява: 745)

Заранее спасибо.

Обновлено: я проанализировал свои журналы, на самом деле контекст регистратора снова инициализируется после уничтожения Log4jServletContextListener.

2016-10-22 13:49:36,347 localhost-startStop-2 DEBUG Log4jServletContextListener, обеспечивающий правильное завершение работы Log4j. 2016-10-22 13:49:36,382 localhost-startStop-2 DEBUG Запуск LoggerContext[name=bb4719, org.apache.logging.log4j.core.LoggerContext@d77214]...

На самом деле в моем приложении я использую Spring ContextLoaderListner в web.xml, поэтому он может использовать внутреннюю регистрацию при уничтожении Spring Listner.

Спасибо


person Reetika    schedule 06.10.2016    source источник


Ответы (2)


Он должен работать.

Убедитесь, что вы включили log4j-web в свою сборку.

Например, как зависимость maven.

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
</dependency>

Если вы используете контейнер сервлета 3.0 или новее (например, в Tomcat 8), дополнительная настройка не требуется (если вы не пропустили Tomcat для сканирования ServletContainerInitializer в определенных банках). Дополнительные сведения см. в разделе Использование Log4j 2 в веб-приложениях.


ОБНОВЛЕНИЕ

Я попробовал это с вашей настройкой (Tomcat 8.0.38, Log4j-2.6.2), и это работает. Чтобы проверить, инициализированы ли Log4jServletContextListener и Log4jServletFilter, установите уровень StatusLogger на DEBUG в вашем log4j2.xml.

<Configuration monitorInterval="30" status="DEBUG">

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

2016-10-14 20:21:36,762 RMI TCP Connection(2)-127.0.0.1 DEBUG Log4jServletContextListener ensuring that Log4j starts up properly.
2016-10-14 20:21:36,764 RMI TCP Connection(2)-127.0.0.1 DEBUG Log4jServletFilter initialized. 

Если ваше приложение повторно развернуто, вы должны увидеть следующие строки в журнале.

2016-10-14 20:22:00,276 RMI TCP Connection(2)-127.0.0.1 DEBUG Log4jServletFilter destroyed.
2016-10-14 20:22:00,286 RMI TCP Connection(2)-127.0.0.1 DEBUG Log4jServletContextListener ensuring that Log4j shuts down properly.

если вы не видите журналы. Вы должны проверить свои catalina.properties, если ваш jarsToSkip содержит какие-либо банки log4j2 или если вы определили параметр isLog4jAutoInitializationDisabled со значением false в вашем web.xml.

<context-param>
   <param-name>isLog4jAutoInitializationDisabled</param-name>
   <param-value>false</param-value>
</context-param> 
person Paul Wasilewski    schedule 06.10.2016
comment
Я использую контейнер servlet 3.0. Но все еще сталкиваюсь с проблемой утечки памяти. Я также изменил catalina.properties, как указано в документе log4j2. - person Reetika; 08.10.2016
comment
@Reetika, сообщите нам, какие именно версии log4j2 и Tomcat 8 вы используете. - person Paul Wasilewski; 08.10.2016
comment
Я использую версию log4j2-2.6.2 и Tomcat8.0.38. Я добавил три jar-файла log4j-web-2.6.2.jar, log4j-core-2.6.2.jar, log4j-api.2.6.2.jar для реализации ведения журнала log4j2. - person Reetika; 08.10.2016
comment
@Reetika, я проверил твои настройки, и они работают. Подробности смотрите в моем обновленном ответе. - person Paul Wasilewski; 14.10.2016
comment
Спасибо @PaulWasilewski за ваше время, я проанализировал свои журналы. - person Reetika; 22.10.2016
comment
Обратите внимание на logging.apache.org/log4j/2.x/manual /webapp.html и добавление необходимых фильтров и слушателей (поскольку мое приложение - Servlet 2.4), похоже, решило мою проблему - person Osmar; 20.07.2017

log4j-web содержит web-fragment.xml:

<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                                  http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
              version="3.0" metadata-complete="true">
    <!-- The Log4j web fragment must be loaded before all other fragments. The configuration below should make this
        happen automatically. If you experience problems, try specifying an <absolute-ordering> in your web.xml
        deployment descriptor. -->
    <name>log4j</name>
    <distributable />
    <ordering>
        <before>
            <others />
        </before>
    </ordering>
</web-fragment>

Важно, чтобы этот фрагмент загружался первым, если веб-приложение содержит более одного фрагмента. Вы настраиваете это в web.xml:

<absolute-ordering>
    <name>log4j</name>
    <others/>
</absolute-ordering>
person sbg    schedule 22.11.2018