Edited for sanity.

Comments surrounded by ==== COMMENT ====

On 8/27/2012 1:24 PM, Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Mark,

On 8/27/12 3:39 PM, Mark Eggers wrote:
This is long and mostly off-topic. Read if you wish to follow the
fun and games of tracking down permgen leaks, especially with a
third party obfuscated library.

:)

JMLPL documentation?

http://tomcat.apache.org/tomcat-6.0-doc/config/listeners.html#JRE_Memory_Leak_Prevention_Listener_-_org.apache.catalina.core.JreMemoryLeakPreventionListener
==== COMMENT ====

Roger that - JMLPL - java memory leak prevention listener - I should have known.

==== COMMENT ====

I'm also stuck with 6.0.x (where x is 35 in development, and 20 in
production). I do not think that upgrading production is a
possibility.

However, I'm seeing this in 6.0.35.

I was referring to this, which was added in 6.0.34:
https://issues.apache.org/bugzilla/show_bug.cgi?id=51688
==== COMMENT ====

Ah, then it's a good thing I do this in the application, since the target platform is 6.0.20.

==== COMMENT ====

It's the same thing you do in your own listener (unless
getSystemEventQueue() does something even worse than simply calling
getDefaultToolkit()).

==== COMMENT ====

All this really does is start the AWT Event Thread. This seems to work fine for both Windows and various flavors of Linux (Fedora, CentOS). It appears to work both with a windowing environment, and without a windowing environment running java.awt.headless=true. At least the thread shows up in thread dumps.

==== COMMENT ====
This was done since the target server was not known (at the time).
Also, this doesn't require changes to a Tomcat server that is not
in my control.

Using the following leak prevention listener configuration didn't
change the fact that there was a leak on unloading the
application.

<Listener
className="org.apache.catalina.core.JreMemoryLeakPreventionListener"


AWTThreadProtection="true"/>

Hmm... does that happen in 6.0.35 as well, or only 6.0.20? It was only
added in 6.0.34 but it should be working. If not, please re-open the
aforementioned bug and explain.
==== COMMENT ====

This does happen in both 6.0.35 and 7.0.27. I know, I know, I'll upgrade to 7.0.29 soon.

==== COMMENT ====

Note that by default I have this configured in my environment.

<Listener
className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>

  According to the documentation, this takes care of many leak
issues, including AppContext.

Right.
==== COMMENT ====

Stack traces deleted to keep everyone sane

==== COMMENT ====

Hmm... that's ... not supposed to happen. The AppContext
leak-prevention has been in Tomcat since back in 2009. Can you confirm
that the JreMemoryLeakProtectionListener is actually being loaded?
==== COMMENT ====

A heap dump (jvisualvm) on the following environments show one instance of the class being loaded.

1. Windows 7, JRE 1.7.0_05, Tomcat 6.0.35
2. Windows 7, JRE 1.7.0_05, Tomcat 7.0.27
3. Windows 7, JRE 1.6.0_32, Tomcat 6.0.35
4. Windows 7, JRE 1.6.0_32, Tomcat 7.0.27
5. CentOS 6.3, JRE 1.6.0_32, Tomcat 6.0.35, -Djava.awt.headless=true
   this is actually running X Windows though
6. CentOS 5.8, JRE 1.6.0_32, Tomcat 6.0.35, -Djava.awt.headless=true
   not running X Windows (dump via jmap)

Hmm - looking at Tomcat 6.0.35 on the CentOS 5.8 system, I see the following when looking at the instance of JreMemoryProtectionListener.

appContextProtection (Z) : true
awtThreadProtection (Z) : true
classesToInitialize (L) : <null>
driverManagerProtection (Z) : true
gcDaemonProtection (Z) : true
ldapPoolProtection (Z) : true
securityLoginConfigurationProtection (Z) : true
securityPolicyProtection (Z) : true
tokenPollerProtection (Z) : true
urlCacheProtection (Z) : true
xmlParsingProtection (Z) : true

And I do have the attribute set to manage the AWT thread (at least on the Tomcat I dumped).

On the Windows (Tomcat 6.0.35, JRE 1.6.0_32), I see the following:

appContextProtection (Z) : true
awtThreadProtection (Z) : false
classesToInitialize (L) : <null>
driverManagerProtection (Z) : true
gcDaemonProtection (Z) : true
ldapPoolProtection (Z) : true
securityLoginConfigurationProtection (Z) : true
securityPolicyProtection (Z) : true
tokenPollerProtection (Z) : true
urlCacheProtection (Z) : true
xmlParsingProtection (Z) : true

which is what I expect from server.xml.

Commenting out the listener (actually it doesn't matter either way since I'm running in a windowed environment) and adding the AWT Event thread protection produces on Windows:

appContextProtection (Z) : true
awtThreadProtection (Z) : true
classesToInitialize (L) : <null>
driverManagerProtection (Z) : true
gcDaemonProtection (Z) : true
ldapPoolProtection (Z) : true
securityLoginConfigurationProtection (Z) : true
securityPolicyProtection (Z) : true
tokenPollerProtection (Z) : true
urlCacheProtection (Z) : true
xmlParsingProtection (Z) : true

And I still see the exact same permgen memory leak upon unloading the application.

The problem looks to be in an internal use of MediaTracker. I suspect that the library uses this to speed image recovery should there be repeated calls.

Unfortunately, these images are dynamically generated, so any use of MediaTracker is pretty worthless in this use case.

There's a way to purge the library caches, and I've experimented with that as well. Unfortunately, it doesn't unregister the images it stored in the MediaTracker. In short, flushing the library's cache in this use case does not address the problem.

. . . thanks for your feedback Chris.
/mde/
==== COMMENT ====

- -chris


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to