Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Jetty/Howto/Prevent Memory Leaks"

< Jetty‎ | Howto
Line 5: Line 5:
 
There's a class of memory leak problems that are caused by code keeping static references to a webapp classloader. As the webapp is undeployed and redeployed, the static reference lives on, meaning that the webapp classloader cannot be garbage collected, and can eventually lead to permgen exhaustion. There's a good discussion of this issue here: [http://cdivilly.wordpress.com/tag/sun-awt-appcontext/]
 
There's a class of memory leak problems that are caused by code keeping static references to a webapp classloader. As the webapp is undeployed and redeployed, the static reference lives on, meaning that the webapp classloader cannot be garbage collected, and can eventually lead to permgen exhaustion. There's a good discussion of this issue here: [http://cdivilly.wordpress.com/tag/sun-awt-appcontext/]
  
We provide a number of [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/util/preventers/package-summary.html|workaround classes] that invoke the problematic code with jetty's classloader, thereby ensuring a webapp's classloader is not pinned.  
+
We provide a number of [http://download.eclipse.org/jetty/stable-7/xref/org/eclipse/jetty/util/preventers/package-summary.html workaround classes] that invoke the problematic code with jetty's classloader, thereby ensuring a webapp's classloader is not pinned.  
  
 
==== Preventers ====
 
==== Preventers ====
Line 11: Line 11:
 
{| border=1
 
{| border=1
 
|+ Preventers
 
|+ Preventers
!Name !! Problem Addressed
+
!Name !! Problem addressed
|AppContextLeakPreventer | The call to AppContext.getAppContext() will keep a static reference to the context classloader. AppContext can be invoked in many different places by the jre.
+
|-
|AWTLeakPreventer |  The java.awt.Toolkit class has a static field that is the default toolkit. Creating the default toolkit causes the creation of an EventQueue, which has a classloader field initialized with the thread context class loader. See [https://issues.jboss.org/browse/AS7-3733]
+
AppContextLeakPreventer || The call to AppContext.getAppContext() will keep a static reference to the context classloader. AppContext can be invoked in many different places by the jre.
|DOMLeakPreventer | DOM parsing can cause the webapp classloader to be pinned, due to the static field RuntimeException of com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser. Note that the bug report at [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6916498] specifically mentions that a heap dump may not identify the GCRoot as the uncollected loader, making it difficult to identify the cause of the leak.
+
|-
|DriverManagerLeakPreventer| java.sql.DriverManager keeps a static reference to the classloader, see java.sql.DriverManager.getCallerClassLoader().
+
AWTLeakPreventer ||  The java.awt.Toolkit class has a static field that is the default toolkit. Creating the default toolkit causes the creation of an EventQueue, which has a classloader field initialized with the thread context class loader. See [https://issues.jboss.org/browse/AS7-3733]
|GCThreadLeakPreventer | * Calls to sun.misc.GC.requestLatency create a daemon thread which keeps a reference to the context classloader. A known caller of this method is the RMI impl. See
+
|-
 +
DOMLeakPreventer || DOM parsing can cause the webapp classloader to be pinned, due to the static field RuntimeException of com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser. Note that the bug report at [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6916498] specifically mentions that a heap dump may not identify the GCRoot as the uncollected loader, making it difficult to identify the cause of the leak.
 +
|-
 +
DriverManagerLeakPreventer || java.sql.DriverManager keeps a static reference to the classloader, see java.sql.DriverManager.getCallerClassLoader().
 +
|-
 +
GCThreadLeakPreventer || Calls to sun.misc.GC.requestLatency create a daemon thread which keeps a reference to the context classloader. A known caller of this method is the RMI impl. See
 
[http://stackoverflow.com/questions/6626680/does-java-garbage-collection-log-entry-full-gc-system-mean-some-class-called].
 
[http://stackoverflow.com/questions/6626680/does-java-garbage-collection-log-entry-full-gc-system-mean-some-class-called].
|Java2DLeakPreventer |sun.java2d.Disposer keeps a reference to the classloader. See [https://issues.apache.org/bugzilla/show_bug.cgi?id=51687]
+
|-
|LDAPLeakPreventer | If com.sun.jndi.LdapPoolManager class is loaded and the system property com.sun.jndi.ldap.connect.pool.timeout is set to a nonzero value, a daemon thread is started keeps a reference to the context classloader.
+
Java2DLeakPreventer || sun.java2d.Disposer keeps a reference to the classloader. See [https://issues.apache.org/bugzilla/show_bug.cgi?id=51687]
|LoginConfigurationLeakPreventer | The javax.security.auth.login.Configuration class keeps a static reference to the thread context classloader.
+
|-
|SecurityProviderLeakPreventer | Some security providers, such as sun.security.pkcs11.SunPKCS11 start a deamon thread which will trap the thread context classloader.
+
LDAPLeakPreventer || If com.sun.jndi.LdapPoolManager class is loaded and the system property com.sun.jndi.ldap.connect.pool.timeout is set to a nonzero value, a daemon thread is started keeps a reference to the context classloader.
 +
|-
 +
LoginConfigurationLeakPreventer || The javax.security.auth.login.Configuration class keeps a static reference to the thread context classloader.
 +
|-
 +
SecurityProviderLeakPreventer || Some security providers, such as sun.security.pkcs11.SunPKCS11 start a deamon thread which will trap the thread context classloader.
 
|}
 
|}
  

Revision as of 01:18, 10 August 2012



Introduction

Well, the most obvious cause of this is memory leaks in your application :) But, if you've thoroughly investigated using tools like jconsole, yourkit, jprofiler, jvisualvm or any of the other profiling and analysis tools out there and you can eliminate your code as the source of the problem, read on.

Preventing WebApp Classloader Pinning

There's a class of memory leak problems that are caused by code keeping static references to a webapp classloader. As the webapp is undeployed and redeployed, the static reference lives on, meaning that the webapp classloader cannot be garbage collected, and can eventually lead to permgen exhaustion. There's a good discussion of this issue here: [1]

We provide a number of workaround classes that invoke the problematic code with jetty's classloader, thereby ensuring a webapp's classloader is not pinned.

Preventers

{

Back to the top