From: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=14042
Using the hotdeploy feature of JBoss with struts enabled applications yields to OutOfMemory-Exceptions. JBoss tries to undeploy the old application and releases all references to it, but the allocated object are never garbage collected. Since this happens with Jetty as well as with Tomcat I assume it's a bug in Struts with cyclic references. Steps to reproduce: 1) Install a vanilla JBoss 3.x 2) Copy jakarta-struts-1.1-b2-blank.war into server/default/deploy 3) Start JBoss 4) Touch/copy server/default/deploy/jakarta-struts-1.1-b2-blank.war 5) Wait a little bit to let JBoss finish the redeploy 6) Go to step 4 Under linux you can see with "ps -p <jboss.pid> -h -o rss" that the memory usage is constantly increasing. With "lsof -p <jboss.pid> | grep jakarta-struts-1.1-b2-blank.war" you can monitor references to the old deployments.
Additional Comments From David Graham 2002-10-29 15:12
It's more likely a bug in JBoss as I haven't heard of this issue before. BTW, at least Sun's jvm handles circular object references so they will get garbage collected. We need more proof that this is a Struts issue. I'll leave this open for now...
Additional Comments From James Mitchell 2002-10-29 17:14
Could you please retest this on an unmodified Tomcat (standalone) install?
Additional Comments From Marco Ladermann 2002-10-30 09:10
Okay, the problem is not JBoss specific. With a plain Tomcat 4.0.6 I added in server.xml a reloadable context: <Context path="/jakarta-struts-1.1-b2-blank" {{{ docBase="jakarta-struts-1.1-b2-blank"
reloadable="true"/>
- }}}
Then I forced reloads every 15 seconds with: while true do {{{ touch webapps/jakarta-struts-1.1-b2-blank/WEB-INF/lib/struts.jar
- sleep 15
ps -p <tomcat.pid> -h -o rss }}}
done and the memory usage increased step by step from 30M to 155M, where the JVM began to throw OutOfMemoryExceptions.
Additional Comments From Rob Leland 2002-10-30 13:25
In a recent nightly build I fixed a bug where the web.xml file was not being closed. Could you try the build from 20021029 to see if the same memory usage occurs ?
Additional Comments From Marco Ladermann 2002-10-30 15:10
Tried build 20021030 and found the same as before. I also saw execption NoRouteToHostException 'cause some dtd resolver wants to connect to the internet. Don't know if that affects the phenomenon.
Additional Comments From Antoni Reus 2002-10-31 18:41
Same problem with Weblogic 6.1SP3
I've followed the same steps
while true do {{{ touch wlserver6.1/config/mydomain/applications/struts-blank.war
- sleep 15
ps -p <tomcat.pid> -h -o rss }}}
done
I used a build from CVS ( dj oct 31 18:30:08 UTC 2002 )
Additional Comments From Antoni Reus 2002-11-07 21:39
I just found this in ActionServlet
{{{ /**
- Gracefully shut down this controller servlet, releasing any resources
- that were allocated at initialization.
- /
- public void destroy() {
- if (log.isDebugEnabled()) {
- log.debug(internal.getMessage("finalizing"));
// FIXME - destroy ApplicationConfig and message resource instances
- if (log.isDebugEnabled()) {
Could this be related with the bug?
In destroyApplications the RequestProcessor.destroy method is invoked on the RequestProcessor of each ApplicationConfig, but the ApplicationConfig itself (now ModuleConfigImpl) aren't processed
Additional Comments From David Graham 2002-11-25 04:49
I'm still not convinced this is a Struts problem. I'm almost certain that circular references are not a problem because Sun's JVM doesn't use reference counting in its garbage collector. What JVM are you using?
As I understand it, to have a Java "memory leak" your app must hold references to unused objects. We're talking about containers reloading an app so all those references should be disposed by the container even if they were being held in error.
Does this behavior happen when you reload a non Struts app?
Additional Comments From Marco Ladermann 2002-11-25 09:30
Okay, circular references should be no problem for a mark & sweep gc. But what about static members holding references to classloaders? Especially in the case of containers that uses shared classloaders. I have seen a static HashMap in the LogFactory class holding such a references for example. In case of shared classloaders those static objects are still reachable, even if the container tries to unload the app. And of course the classloader of the app to unload is also still reachable via the static object.
Additional Comments From Craig McClanahan 2002-12-18 07:38
I tried your test against stand-alone Tomcat 4.1.17 (just released for general availability), using the manager reload command to initiate the reloads, and observed basically the same behavior. I suspect you may be correct about static resources being maintained for things like LogFactory (Tomcat ships with commons-logging-api in the common/lib directory).
As an experiment, I've added a method to LogFactory that lets you clear the LogFactory instance (and associated Log instances) for a single class loader, and then modified ActionServlet.destroy() to call this method. Memory still went up -- but at a slightly lower pace -- but I still eventually ran out. As such, I'm pretty suspicious that this is really a container problem, but this needs more investigation.
Additional Comments From Marcus Brito 2003-01-14 15:52
Just to add some comment: I've seen many other reports about memory leaks in JBoss deployments, weather an application uses struts or not. So it does not seems to be anything specific to struts -- it's a JBoss (or web container, or JVM) issue.
Additional Comments From Ted Husted 2003-01-19 19:17
Since indications are this is a container issue, we can visit in the 1.2.x timeframe.
Additional Comments From Kenneth Baltz 2003-08-20 20:12
It's anecdotal evidence, but I definitely experienced this problem with Tomcat, without using Struts. I always thought maybe it was something I was doing, but I suspect it has more to do with how Tomcat cleans up the old "instance" of your webapp when you reload it.