Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: 0.9.13
-
Fix Version/s: None
-
Component/s: Perf4J base
-
Labels:None
-
Environment:Mac OSX, Java 1.6.0_20, Tomcat 6.0.26
-
Number of attachments :
Description
When you restart a servlet context (NOT the whole container), the perf4j-async-stats-appender-sink-CoalescingStatistics thread is not properly shut down. This causes a memory leak, as it means that the original class loader used stays in memory.
As Tomcat says:
SEVERE: A web application appears to have started a thread named [perf4j-async-stats-appender-sink-CoalescingStatistics] but has failed to stop it. This is very likely to create a memory leak.
When the web application then restarts, it spews some nasty errors into the log:
Exception in thread "perf4j-async-stats-appender-sink-CoalescingStatistics" java.lang.NoClassDefFoundError: org/apache/log4j/spi/NOPLoggerRepository at org.apache.log4j.LogManager.getLoggerRepository(LogManager.java:197) at org.apache.log4j.LogManager.getLogger(LogManager.java:228) at org.apache.log4j.Logger.getLogger(Logger.java:104) at org.perf4j.log4j.AsyncCoalescingStatisticsAppender$1.handle(AsyncCoalescingStatisticsAppender.java:191) at org.perf4j.helpers.GenericAsyncCoalescingStatisticsAppender$Dispatcher.run(GenericAsyncCoalescingStatisticsAppender.java:316) at java.lang.Thread.run(Thread.java:637) Caused by: java.lang.ClassNotFoundException: org.apache.log4j.spi.NOPLoggerRepository at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1516) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1361) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:398) ... 6 more
For further information, please see http://wiki.apache.org/tomcat/MemoryLeakProtection.
This is in no way Tomcat-specific, but Tomcat allowed me to detect this error.
Since this is not a JVM shutdown, the code which currenly exists does not properly detect the condition. One practical suggestion would be to provide a global Perf4j.shutdown() which can be called from a ServletContextListener upon contextDestroyed().
Um... Ping? Is Perf4j dead?