Tomcat log4j2线程内存泄漏问题

Ree*_*ika 7 java log4j2 tomcat8 java-threads

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

以下是卡特琳娜日志:

2016 年 10 月 6 日 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.爪哇: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 调试启动 LoggerContext[name=bb4719, org.apache.logging.log4j.core.LoggerContext@d77214]...

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

谢谢

Pau*_*ski 6

它应该有效。

确保您将其包含log4j-web在构建中。

例如作为 Maven 依赖项。

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 servlet 3.0 容器或更新版本(如 Tomcat 8),则不需要额外的配置(只要您没有省略 Tomcat 扫描某些 jar 中的 ServletContainerInitializer)。有关更多信息,请参阅在 Web 应用程序中使用 Log4j 2


更新

我已经尝试使用您的设置(Tomcat 8.0.38,Log4j-2.6.2)并且它可以工作。要检查 和 是否Log4jServletContextListenerLog4jServletFilter初始化,请StatusLoggerDEBUG您的log4j2.xml.

<Configuration monitorInterval="30" status="DEBUG">
Run Code Online (Sandbox Code Playgroud)

之后,当部署应用程序时,您应该能够在根记录器附加程序中看到以下输出。

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. 
Run Code Online (Sandbox Code Playgroud)

如果您的应用程序被重新部署,您应该在日志中看到以下几行。

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.
Run Code Online (Sandbox Code Playgroud)

如果您没有看到日志。jarsToSkip如果您包含 log4j2 的任何 jar,或者您是否使用 web.xml 中的isLog4jAutoInitializationDisabled值定义了参数,您应该检查您的 catalina.properties 。false

<context-param>
   <param-name>isLog4jAutoInitializationDisabled</param-name>
   <param-value>false</param-value>
</context-param> 
Run Code Online (Sandbox Code Playgroud)