java - log4j2线程的Tomcat内存泄漏问题

标签 java log4j2 tomcat8 java-threads

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

下面是catalina日志:

06-Oct-2016 15:13:55.927 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [mywebapp] appears to have started a thread named [Log4j2-Log4j2Scheduled-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: sun.misc.Unsafe.park(Native Method) 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)

提前致谢。

更新: 我分析了我的日志,实际上,一旦 Log4jServletContextListener 被破坏,记录器上下文就会再次初始化。

2016-10-22 13:49:36,347 localhost-startStop-2 DEBUG Log4jServletContextListener ensuring that Log4j shuts down properly. 2016-10-22 13:49:36,382 localhost-startStop-2 DEBUG Starting LoggerContext[name=bb4719, org.apache.logging.log4j.core.LoggerContext@d77214]...

实际上,在我的应用程序中,我在 web.xml 中使用了 spring ContextLoaderListner,因此它可能会在破坏 spring listner 的同时在内部使用日志记录。

谢谢

最佳答案

它应该可以工作。

确保您在构建中包含 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 是否已初始化,请在 log4j2 中将 StatusLogger 级别设置为 DEBUG .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.

如果您没有看到日志。如果您的 jarsToSkip 包含任何 log4j2 的 jar,或者如果您定义了一个 isLog4jAutoInitializationDisabled 参数,其值为 false,您应该检查您的 catalina.properties你的 web.xml。

<context-param>
   <param-name>isLog4jAutoInitializationDisabled</param-name>
   <param-value>false</param-value>
</context-param> 

关于java - log4j2线程的Tomcat内存泄漏问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39902747/

相关文章:

java - 在weblogic中从AD获取自定义用户属性

java - log4j2.xml 中每个包的 Log4J 不同日志级别

java - Tomcat8 部署时挂起

java - 通过 Spring Boot 应用程序关闭 Tomcat 日志记录

linux - linux 上 tomcat 8 服务器的控制台输出

java - Flink 定时器没有按时执行

java - Hadoop DistributedCache 对象在作业期间更改

JavaFx:格式化表列数据

java - 如何使用 Spring Boot 应用程序初始化 log4j?

java - KARATE:打印语句不会使用 log4j2 写入控制台