|  | <html><head> | 
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | 
|  | <title>Preventing Memory Leaks</title><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><meta name="keywords" content="jetty, servlet, servlet-api, cometd, http, websocket, eclipse, maven, java, server, software"><link rel="home" href="index.html" title="Jetty : The Definitive Reference"><link rel="up" href="troubleshooting.html" title="Chapter 35. Troubleshooting"><link rel="prev" href="troubleshooting-locked-files-on-windows.html" title="Troubleshooting Locked Files on Windows"><link rel="next" href="security-reports.html" title="Jetty Security Reports"><link xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" rel="shortcut icon" href="images/favicon.ico"><script type="text/javascript" src="js/shCore.js"></script><script type="text/javascript" src="js/shBrushJava.js"></script><script type="text/javascript" src="js/shBrushXml.js"></script><script type="text/javascript" src="js/shBrushBash.js"></script><script type="text/javascript" src="js/shBrushJScript.js"></script><script type="text/javascript" src="js/shBrushSql.js"></script><script type="text/javascript" src="js/shBrushProperties.js"></script><script type="text/javascript" src="js/shBrushPlain.js"></script><link type="text/css" rel="stylesheet" href="css/shCore.css"><link type="text/css" rel="stylesheet" href="css/shThemeEclipse.css"><link type="text/css" rel="stylesheet" href="css/font-awesome.min.css"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><tr><td style="width: 25%"><a href="http://www.eclipse.org/jetty"><img src="images/jetty-header-logo.png" alt="Jetty Logo"></a><br><span style="font-size: small"> | 
|  | Version: 9.3.0.v20150612</span></td><td style="width: 50%"><script type="text/javascript">  (function() { | 
|  | var cx = '016459005284625897022:obd4lsai2ds'; | 
|  | var gcse = document.createElement('script'); | 
|  | gcse.type = 'text/javascript'; | 
|  | gcse.async = true; | 
|  | gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + | 
|  | '//www.google.com/cse/cse.js?cx=' + cx; | 
|  | var s = document.getElementsByTagName('script')[0]; | 
|  | s.parentNode.insertBefore(gcse, s); | 
|  | })(); | 
|  | </script><gcse:search></gcse:search></td></tr></table><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Preventing Memory Leaks</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="troubleshooting-locked-files-on-windows.html"><i class="icon-chevron-left"></i> Previous</a> </td><th width="60%" align="center">Chapter 35. Troubleshooting<br><a accesskey="p" href="index.html"><i class="icon-home"></i> Home</a></th><td width="20%" align="right"> <a accesskey="n" href="security-reports.html">Next <i class="icon-chevron-right"></i></a></td></tr></table><hr></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="jetty-callout"><h5 class="callout"><a href="http://www.webtide.com/">Contact the core Jetty developers at | 
|  | <span class="website">www.webtide.com</span></a></h5><p> | 
|  | private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... | 
|  | scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery | 
|  | </p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="preventing-memory-leaks"></a>Preventing Memory Leaks</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="preventing-memory-leaks.html#preventing-webapp-classloader-pinning">Preventing WebApp Classloader Pinning</a></span></dt><dt><span class="section"><a href="preventing-memory-leaks.html#jsp-bugs">JSP Bugs: Permgen Problems</a></span></dt><dt><span class="section"><a href="preventing-memory-leaks.html#jvm-bugs">JVM Bugs</a></span></dt></dl></div><p>If you have memory leaks, and you have thoroughly investigated tools | 
|  | like jconsole, yourkit, jprofiler, jvisualvm or any of the other profiling | 
|  | and analysis tools, and you can eliminate your code as the source of the | 
|  | problem, read the following sections about how to prevent memory leaks in | 
|  | your application.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="preventing-webapp-classloader-pinning"></a>Preventing WebApp Classloader Pinning</h3></div></div></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><i class="icon-asterisk"></i> Note</h3><p>This feature is available for Jetty 7.6.6 and later.</p></div><p>Code that keeps references to a webapp classloader can cause memory | 
|  | leaks. These leaks fall generally into two categories: static fields and | 
|  | daemon threads.</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>A static field is initialized with the value of the classloader, | 
|  | which happens to be a webapp classloader; as Jetty undeploys and | 
|  | redeploys the webapp, the static reference lives on, meaning garbage | 
|  | collecting cannot occur for the webapp classloader.</p></li><li class="listitem"><p>When Jetty starts as a daemon thread and is outside the | 
|  | lifecycle of the webapp, threads have references to the context | 
|  | classloader that created them, leading to a memory leak if that | 
|  | classloader belongs to a webapp. For a good discussion of the issue | 
|  | see <a class="link" href="http://cdivilly.wordpress.com/tag/sun-awt-appcontext/" target="_top"> | 
|  | Anatomy of a PermGen Memory Leak.</a></p></li></ul></div><p>We provide a number of <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs//org/eclipse/jetty/util/preventers/package-summary.html" target="_top"> | 
|  | workaround classes</a> that preemptively invoke the problematic code | 
|  | with the Jetty classloader, thereby ensuring the webapp classloader is not | 
|  | pinned. Be aware that since some of the problematic code creates threads, | 
|  | you should be selective about which preventers you enable, and use only | 
|  | those that are specific to your application.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="preventers-table"></a>Preventers</h4></div></div></div><p>Jetty includes the following preventers.</p><div class="informaltable"><table border="1"><colgroup><col><col></colgroup><thead><tr><th align="left">Preventer Name</th><th align="left">Problem Addressed</th></tr></thead><tbody><tr><td>AppContextLeakPreventer</td><td>The call to <code class="code">AppContext.getAppContext()</code> keeps | 
|  | a static reference to the context classloader. The JRE can | 
|  | invoke AppContext in many different places.</td></tr><tr><td>AWTLeakPreventer</td><td>The <code class="code">java.awt.Toolkit</code> class has a static | 
|  | field that is the default toolkit. Creating the default toolkit | 
|  | causes the creation of an <code class="code">EventQueue</code>, which has a | 
|  | classloader field initialized with the thread context class | 
|  | loader. See <a class="link" href="https://issues.jboss.org/browse/AS7-3733" target="_top">JBoss bug | 
|  | AS7-3733.</a></td></tr><tr><td>DOMLeakPreventer</td><td>DOM parsing can cause the webapp classloader to be | 
|  | pinned, due to the static field <code class="code"> RuntimeException</code> | 
|  | of <code class="code"> | 
|  | com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser.</code> | 
|  | <a class="link" href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6916498" target="_top">Oracle | 
|  | bug 6916498</a> specifically mentions that a heap dump might | 
|  | not identify the GCRoot as the uncollected loader, making it | 
|  | difficult to identify the cause of the leak.</td></tr><tr><td>DriverManagerLeakPreventer</td><td>The number of threads dedicated to accepting incoming | 
|  | connections.</td></tr><tr><td>GCThreadLeakPreventer</td><td>Calls to <code class="code">sun.misc.GC.requestLatency</code> create a | 
|  | daemon thread that keeps a reference to the context classloader. | 
|  | A known caller of this method is the RMI impl. See <a class="link" href="http://stackoverflow.com/questions/6626680/does-java-garbage-collection-log-entry-full-gc-system-mean-some-class-called" target="_top">Stackoverflow: | 
|  | Does java garbage collection log entry 'Full GC system' mean | 
|  | some class called System.gc()?</a></td></tr><tr><td>Java2DLeakPreventer</td><td><code class="code">sun.java2d.Disposer</code> keeps a reference to the | 
|  | classloader. See <a class="link" href="https://issues.apache.org/bugzilla/show_bug.cgi?id=51687" target="_top">ASF | 
|  | bug 51687.</a></td></tr><tr><td>LDAPLeakPreventer</td><td>If <code class="code">com.sun.jndi.LdapPoolManager</code> class is | 
|  | loaded and the system property <code class="code"> | 
|  | com.sun.jndi.ldap.connect.pool.timeout</code> is set to a | 
|  | nonzero value, a daemon thread starts and keeps a reference to | 
|  | the context classloader.</td></tr><tr><td>LoginConfigurationLeakPreventer</td><td>The <code class="code">javax.security.auth.login.Configuration</code> | 
|  | class keeps a static reference to the thread context | 
|  | classloader.</td></tr><tr><td>SecurityProviderLeakPreventer</td><td>Some security providers, such as | 
|  | <code class="code">sun.security.pkcs11.SunPKCS11</code> start a deamon thread | 
|  | that traps the thread context classloader.</td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="configuring-preventers"></a>Configuring Preventers</h4></div></div></div><p>You can individually enable each preventer by adding an instance | 
|  | to a Server with the <code class="code"> addBean(Object)</code> call. Here's an | 
|  | example of how to do it in code with the <code class="code"> | 
|  | org.eclipse.jetty.util.preventers.AppContextLeakPreventer</code>:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false"> | 
|  | <![CDATA[ | 
|  |  | 
|  | Server server = new Server(); | 
|  | server.addBean(new AppContextLeakPreventer()); | 
|  |  | 
|  | ]]> | 
|  | </script></div><p>You can add the equivalent in code to the | 
|  | <code class="code">$JETTY_HOME/etc/jetty.xml</code> file or any jetty xml file that | 
|  | is configuring a Server instance. Be aware that if you have more than | 
|  | one Server instance in your JVM, you should configure these preventers | 
|  | on just <span class="emphasis"><em>one</em></span> of them. Here's the example from code | 
|  | put into xml:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false"> | 
|  | <![CDATA[ | 
|  |  | 
|  | <Configure id="Server" class="org.eclipse.jetty.server.Server"> | 
|  |  | 
|  | <Call name="addBean"> | 
|  | <Arg> | 
|  | <New class="org.eclipse.jetty.util.preventers.AppContextLeakPreventer"/> | 
|  | </Arg> | 
|  | </Call> | 
|  |  | 
|  | </Configure> | 
|  |  | 
|  | ]]> | 
|  | </script></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="jsp-bugs"></a>JSP Bugs: Permgen Problems</h3></div></div></div><p>The JSP engine in Jetty is Jasper. This was originally developed | 
|  | under the Apache Tomcat project, but over time many different project have | 
|  | forked it. All Jetty versions up to 6 used Apache-based Jasper | 
|  | exclusively, with Jetty 6 using Apache Jasper only for JSP 2.0. With the | 
|  | advent of JSP 2.1, Jetty 6 switched to using Jasper from Sun's <a class="link" href="https://glassfish.java.net/" target="_top">Glassfish</a> project, which is | 
|  | now the reference implementation.</p><p>All forks of Jasper suffer from a problem whereby using JSP tag | 
|  | files puts the permgen space under pressure. This is because of the | 
|  | classloading architecture of the JSP implementation. Each JSP file is | 
|  | effectively compiled and its class loaded in its own classloader to allow | 
|  | for hot replacement. Each JSP that contains references to a tag file | 
|  | compiles the tag if necessary and then loads it using its own classloader. | 
|  | If you have many JSPs that refer to the same tag file, the tag's class is | 
|  | loaded over and over again into permgen space, once for each JSP. See | 
|  | <a class="link" href="http://java.net/jira/browse/GLASSFISH-3963" target="_top">Glassfish bug | 
|  | 3963</a> and <a class="link" href="https://issues.apache.org/bugzilla/show_bug.cgi?id=43878" target="_top">Apache | 
|  | bug 43878.</a> The Apache Tomcat project has already closed this bug | 
|  | with status WON'T FIX, however the Glassfish folks still have the bug open | 
|  | and have scheduled it to be fixed. When the fix becomes available, the | 
|  | Jetty project will pick it up and incorporate into our release | 
|  | program.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="jvm-bugs"></a>JVM Bugs</h3></div></div></div><p>This section describes garbage collection and direct ByteBuffer | 
|  | problems.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="jvm-garbage-collection-problems"></a>Garbage Collection Problems</h4></div></div></div><p>One symptom of a cluster of JVM related memory issues is the OOM | 
|  | exception accompanied by a message such as | 
|  | <code class="code">java.lang.OutOfMemoryError: requested xxxx bytes for xxx. Out of | 
|  | swap space?</code></p><p><a class="link" href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4697804" target="_top">Oracle | 
|  | bug 4697804</a> describes how this can happen in the scenario when | 
|  | the garbage collector needs to allocate a bit more space during its run | 
|  | and tries to resize the heap, but fails because the machine is out of | 
|  | swap space. One suggested work around is to ensure that the JVM never | 
|  | tries to resize the heap, by setting min heap size to max heap | 
|  | size:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false"> | 
|  | <![CDATA[ | 
|  |  | 
|  | java -Xmx1024m -Xms1024m | 
|  |  | 
|  | ]]> | 
|  | </script></div><p>Another workaround is to ensure you have configured sufficient | 
|  | swap space on your device to accommodate all programs you are running | 
|  | concurrently.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="direct-byte-buffers"></a>Direct ByteBuffers</h4></div></div></div><p>Exhausting native memory is another issue related to JVM bugs. The | 
|  | symptoms to look out for are the process size growing, but heap use | 
|  | remaining relatively constant. Both the JIT compiler and nio ByteBuffers | 
|  | can consume native memory. <a class="link" href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6210541" target="_top">Oracle | 
|  | bug 6210541</a> discusses a still-unsolved problem whereby the JVM | 
|  | itself allocates a direct ByteBuffer in some circumstances while the | 
|  | system never garbage collects, effectively eating native memory. Guy | 
|  | Korland's blog discusses this problem <a class="link" href="http://www.jroller.com/gkorland/entry/java_s_memory_isn_t" target="_top">here</a> | 
|  | and <a class="link" href="http://www.jroller.com/gkorland/entry/java_s_memory_managment_is" target="_top">here.</a> | 
|  | As the JIT compiler consumes native memory, the lack of available memory | 
|  | may manifest itself in the JIT as OutOfMemory exceptions such as | 
|  | <code class="code">Exception in thread "CompilerThread0" java.lang.OutOfMemoryError: | 
|  | requested xxx bytes for ChunkPool::allocate. Out of swap | 
|  | space?</code></p><p>By default, Jetty allocates and manages its own pool of direct | 
|  | ByteBuffers for io if you configure the nio SelectChannelConnector. It | 
|  | also allocates MappedByteBuffers to memory-map static files via the | 
|  | DefaultServlet settings. However, you could be vulnerable to this JVM | 
|  | ByteBuffer allocation problem if you have disabled either of these | 
|  | options. For example, if you're on Windows, you may have disabled the | 
|  | use of memory-mapped buffers for the static file cache on the | 
|  | DefaultServlet to avoid the file-locking problem.</p></div></div></div><script type="text/javascript"> | 
|  | SyntaxHighlighter.all() | 
|  | </script><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="troubleshooting-locked-files-on-windows.html"><i class="icon-chevron-left"></i> Previous</a> </td><td width="20%" align="center"><a accesskey="u" href="troubleshooting.html"><i class="icon-chevron-up"></i> Top</a></td><td width="40%" align="right"> <a accesskey="n" href="security-reports.html">Next <i class="icon-chevron-right"></i></a></td></tr><tr><td width="40%" align="left" valign="top">Troubleshooting Locked Files on Windows </td><td width="20%" align="center"><a accesskey="h" href="index.html"><i class="icon-home"></i> Home</a></td><td width="40%" align="right" valign="top"> Jetty Security Reports</td></tr></table></div><p xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><div class="jetty-callout"> | 
|  | See an error or something missing? | 
|  | <span class="callout"><a href="http://github.com/jetty-project/jetty-documentation">Contribute to this documentation at | 
|  | <span class="website"><i class="icon-github"></i> Github!</span></a></span><span style="float: right"><i>(Generated: 2015-06-15T13:18:56-05:00)</i></span></div></p><script xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" type="text/javascript"> | 
|  | var _gaq = _gaq || []; | 
|  | _gaq.push(['_setAccount', 'UA-1149868-7']); | 
|  | _gaq.push(['_trackPageview']); | 
|  |  | 
|  | (function() { | 
|  | var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | 
|  | ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | 
|  | var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | 
|  | })(); | 
|  | </script></body></html> |