Are there any known problems with using the Tomcat manager app to
shutdown web apps that use log4j? I have a web app that leaks memory
everytime I use the manager app to shut it down. To help narrow the
problem down, I set up a simple web app with one servlet and log4j
1.2.8. Depending on what type of log4j configuration the web app uses,
the web app classloader does not get garbage collected which means all
of the classes it loaded and any static references that these classes
may have all stay in memory. When the manager app is used to restart
the app, a new webapp class loader is created and the classes for the
web are loaded again. The old class loader is pinned in memory by some
reference.
All tests used this log4j configuration in log4j.properties:
log4j.debug=true
log4j.rootLogger=DEBUG, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
Each test deployed log4j.jar in the web app context class path. A URI
of the web app was invoked to load the web app's servlet. The app was
then shutdown using the Tomcat manager app. A memory snapshot was then
taken with YourKit Java Profiler 2.5.1 to inspect the classes and
instances still remaining in memory.
Test 1: Simple layout:
log4j.appender.CONSOLE.layout=org.apache.log4j.SimpleLayout
Result: successful - web app garbage collected
Test 2: Pattern layout with no conversion pattern specified:
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
Result: successful - web app garbage collected
Test 3: Pattern layout with a conversion pattern specified:
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{DATE} %t %-5p [%x] %c
%m%n
Result: unsuccessful - web app and tomcat webapp classloader still in
memory - not garbage collected
Test 4: Log4J configured with call to BasicConfigurator.configure()
instead of using log4j.properties file.
Result: successful - web app garbage collected
Test 5: Same as Test 3 except now log4j.jar deployed in
tomcat/shared/lib classpath instead of web app context class path:
Result: successful - web app garbage collected (log4j classes and
instances still in memory since the shared class path classloader is not
reloaded)
Am I doing something wrong or out of the ordinary here or is there some
issue with the configuration of a ConversionPattern using the properties
file? Is it possible that something in this code is holding onto a
reference to the web app class loader or some class of the web app?
Any feedback is appreciated.
-Jay
Environment
Tomcat 4.1.30
Sun JDK 1.4.2-05
Windows XP
log4j 1.2.8
***** SimpleServlet.java:
package z;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.apache.log4j.BasicConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
public class SimpleServlet extends HttpServlet {
private static Logger log =
LogManager.getLogger(SimpleServlet.class);
public void init(ServletConfig servletConfig) throws ServletException
{
super.init(servletConfig);
// This fixes it too when you do basic configuration instead of
log4j.properties
// Notice that the basic configuration uses the PatternLayout with
a ConversionPattern
// THe problem must be in the parsing of the Pattern or
Configuring of options
// when using log4j.properties?
// Uncomment the next two lines for test 4
//System.out.println("basic configuration");
//BasicConfigurator.configure();
}
protected void doGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws ServletException,
IOException {
PrintWriter out = httpServletResponse.getWriter();
out.write("<html><head></head><body>" +
"Hello World " + new Date() +
"</body></html>");
out.flush();
}
public void destroy(){
super.destroy();
LogManager.shutdown();
System.out.println("Done");
}
}
***** web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application
2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>simpleservlet</servlet-name>
<servlet-class>z.SimpleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>simpleservlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]