我正在尝试在Web应用程序中诊断生产内存泄漏。该应用程序是在Tomcat 7和mySQL上运行的GWT应用程序,在Debian上运行OpenJDK 1.6.0_18。
我启动了tomcat并让应用程序泄漏了几天 - 没有重新加载应用程序 - 然后进行堆转储并在Eclipse MAT插件中打开它。我正试图理解我所看到的。看来tomcat登录类中有大量的内存(见下面的截图)。
我使用java日志框架在GWT servlet中进行基本日志记录。只是像
这样的基本调用Logger.getAnonymousLogger().log(Level.INFO, "User" + userId + " did something interesting");
Logger.getAnonymousLogger().log(Level.SEVERE, exception.getMessage(), exception);
我在网上找到的唯一类似问题是blog post。
任何人都可以解释这里可能发生的事情吗?为什么tomcat日志记录类会占用如此多的内存?
为了使我更加困惑,它似乎抓住了大量的弱引用 - 但我似乎无法在MAT中弄清楚如何找出这些弱引用指向的内容,我也会期望在达到堆限制时收集弱引用,但tomcat会抛出内存异常。
答案 0 :(得分:3)
有趣的问题:)
看起来有数百万个类已经使用您的RootLogger注册了记录器。现在,除非您的项目中有数百万个类,否则:
new Logger(name)
无论哪种方式,每个额外的记录器都会向包含弱引用的ArrayList添加另一行。弱引用通过指向记录器启动,但记录器正在进行GC,只留下空的弱引用。大量的弱引用导致OOM而不是它们(习惯)指向的对象。
修复?
LogManager.addLogger
。如果是,请强制记录器名称为常量new Logger(variable)
之类的内容。如果这样做,那么您需要将变量更改为常量。