ASF Bugzilla – Attachment 27038 Details for
Bug 51195
"Find leaks" reports a false positive memory/classloader leak
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Implements the suggested change in StandardHost
FlushObjectStreamClassCaches.diff (text/plain), 4.46 KB, created by
Joern Huxhorn
on 2011-05-19 17:19:01 UTC
(
hide
)
Description:
Implements the suggested change in StandardHost
Filename:
MIME Type:
Creator:
Joern Huxhorn
Created:
2011-05-19 17:19:01 UTC
Size:
4.46 KB
patch
obsolete
>Index: java/org/apache/catalina/core/StandardHost.java >=================================================================== >--- java/org/apache/catalina/core/StandardHost.java (Revision 1124979) >+++ java/org/apache/catalina/core/StandardHost.java (Arbeitskopie) >@@ -17,12 +17,15 @@ > package org.apache.catalina.core; > > >+import java.lang.reflect.Field; >+ > import java.util.ArrayList; > import java.util.List; > import java.util.Locale; > import java.util.Map; > import java.util.WeakHashMap; > import java.util.regex.Pattern; >+import java.util.concurrent.ConcurrentHashMap; > > import org.apache.catalina.Container; > import org.apache.catalina.Context; >@@ -635,6 +638,8 @@ > */ > public String[] findReloadedContextMemoryLeaks() { > >+ preventObjectStreamFalsePositives(); >+ > System.gc(); > > List<String> result = new ArrayList<String>(); >@@ -653,6 +658,82 @@ > } > > /** >+ * This method performs additional cleanup to work around the issue described in LBCORE-205 (Logback JIRA) >+ * and https://issues.apache.org/bugzilla/show_bug.cgi?id=51195 >+ * >+ * The class java.io.ObjectStreamClass, which is used for serialization, has an internal class Caches >+ * that keeps SoftReferences to classes previously (de)serialized. This causes a semi-leak since it prevents >+ * unloading of those classes (and their classloader, including all other loaded classes) until memory is >+ * running really low, forcing the SoftReferences to be collected by the garbage collection. >+ * >+ * This, in turn, causes a leak warning in Tomcat 7 leak-detection. >+ * One could argue that this is a false positive since the webapp will, at some point, be completely collected. >+ * >+ * Regardless of this point, the fix below will, beside fixing the warning, relieve stress from the garbage >+ * collector, since the amount of memory kept by a webapp classloader can be quite significant. >+ * Freeing up those resources as soon as possible does make sense in any case. >+ * >+ * Calling the method below should be quite safe. >+ * All relevant exceptions (including SecurityException) are handled properly. >+ * Clearing the maps in Caches is a safe operation, too, since they are instances of ConcurrentMap and clear() >+ * is performed atomic. Sudden cleanup of those maps would occur "naturally" in case of low memory, anyway. >+ * >+ * The only small "downside" will be a little bit of slowdown in case of further (de)serialization directly >+ * afterwards since the caches will need to be repopulated. >+ */ >+ private void preventObjectStreamFalsePositives() { >+ Throwable t=null; >+ String className = "java.io.ObjectStreamClass$Caches"; >+ try { >+ Class clazz = Class.forName(className); >+ clearStaticConcurrentHashMap(clazz, "localDescs"); >+ clearStaticConcurrentHashMap(clazz, "reflectors"); >+ } catch (ClassNotFoundException e) { >+ t = e; >+ } catch (SecurityException e) { >+ t = e; >+ } >+ >+ if(t != null) { >+ // ignore >+ // this would be the right place to add some info that flushing >+ // did not work out. >+ // no harm is done, though >+ } >+ } >+ >+ >+ private void clearStaticConcurrentHashMap(Class clazz, String fieldName) { >+ Throwable t=null; >+ try { >+ Field field = clazz.getDeclaredField(fieldName); >+ field.setAccessible(true); >+ Object value = field.get(null); >+ if(value instanceof ConcurrentHashMap) { >+ ConcurrentHashMap map = (ConcurrentHashMap) value; >+ map.clear(); >+ } else { >+ // ignore >+ // this would be the right place to add some info that flushing >+ // of the field did not work out. >+ // no harm is done, though >+ } >+ } catch (NoSuchFieldException e) { >+ t = e; >+ } catch (IllegalAccessException e) { >+ t = e; >+ } catch (SecurityException e) { >+ t = e; >+ } >+ if(t != null) { >+ // ignore >+ // this would be the right place to add some info that flushing >+ // of the field did not work out. >+ // no harm is done, though >+ } >+ } >+ >+ /** > * Return the set of alias names for this Host. If none are defined, > * a zero length array is returned. > */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 51195
: 27038 |
29258