2017-08-16 54 views
1

我目前正在迁移我们的web服务和web应用程序以使用Log4j 2.6日志记录。根据网站上提供的信息,Web应用程序支持部分无垃圾日志记录,并且由于可能存在内存泄漏,因此不支持完全无垃圾日志记录。任何人都可以帮助我理解,如果我们在第一种情况下启用TreadLocal并在第二种情况下设置ThreadLocal禁用,日志记录是如何工作的。为什么log4j gc自由日志不适合web应用程序

此外,我想知道在什么情况下部分垃圾免费日志记录比完全垃圾免费日志记录更好。

回答

0

在无垃圾模式下,Log4j2重用LogEvent对象。为了防止多个线程同时修改相同的LogEvent,每个线程都有自己的LogEvent。这是用ThreadLocal实现的。

ThreadLocals的一个关键点是,无论放在它们中什么都保留在那里,直到它被明确移除或线程死亡。即使没有其他对我们的LogEvent的引用,它也不会被垃圾收集,因为ThreadLocal仍然有对它的引用,并且线程是GC根。

Web应用程序容器通常会在自定义类加载器中加载Web应用程序。这允许在不重新启动Web应用程序容器的情况下停止并重新加载不同版本的Web应用程序。但是,如果仍有某个Web应用程序的前一个版本的类的引用,则该类和所有关联的类(包括自定义类加载器)不能被垃圾收集。

什么时候会发生这种情况?当Web应用程序容器具有在Web应用程序之间共享的线程池时,并且在Web应用程序重新加载时不刷新。然后,池中的线程仍然具有对LogEvent对象和以前版本的Web应用程序的类的ThreadLocal引用,所以此类不能被垃圾回收,并且存在内存泄漏。

结论 您可以使用垃圾免费登录的Web应用程序,如果同时满足以下两个条件:

  1. 线程池是不是web应用程序之间共享
  2. 当一个Web应用程序重新加载,其线程池也关闭并重新启动

如果上述都是真的,我相信你可以配置Log4j2使用无垃圾日志没有风险内存泄漏。当然,你需要做尽职调查和测试。