Tomcat内存泄漏问题的log4j2线程

时间:2016-10-06 17:59:48

标签: java log4j2 tomcat8 java-threads

我正在使用log4j2进行日志记录,tomcat8和java8版本。 我使用属性“monitorInterval”来定期检查我的log4j2.xml。 在关机期间我的tomcat我面临内存泄漏问题。如何解决这个内存泄漏问题?

以下是catalina日志:

  

06-Oct-2016 15:13:55.927警告[localhost-startStop-2]   org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads   Web应用程序[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.java:745)

提前致谢。

更新: 我分析了我的日志,实际上Logger上下文在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 [名称= bb4719,   org.apache.logging.log4j.core.LoggerContext@d77214] ...

实际上在我的应用程序中我在web.xml中使用spring ContextLoaderListner,所以它可能在内部使用日志记录而破坏spring listner。

由于

2 个答案:

答案 0 :(得分:4)

它应该工作。

确保在构建中包含log4j-web

例如作为maven依赖。

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

如果您使用的是servlet 3.0容器或更新版本(如Tomcat 8中所示),则无需进行其他配置(只要您没有省略Tomcat在某些jar中扫描ServletContainerInitializer)。有关详细信息,请参阅Using Log4j 2 in Web Applications

<强>更新

我已经设置了它(Tomcat 8.0.38,Log4j-2.6.2)并且它可以工作。要检查Log4jServletContextListenerLog4jServletFilter是否已初始化,请将StatusLogger级别设置为DEBUG中的log4j2.xml

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

之后,您应该能够在部署应用程序时看到root logger appender中的以下输出。

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.

如果您没有看到日志。如果您的jarsToSkip包含任何jar的log4j2,或者您已在web.xml中定义了值为isLog4jAutoInitializationDisabled的{​​{1}}参数,则应检查catalina.properties。

false

答案 1 :(得分:0)

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>

如果webapp包含多个片段,则首先加载此片段很重要。您可以在web.xml中进行配置:

<absolute-ordering>
    <name>log4j</name>
    <others/>
</absolute-ordering>