Re: More sources of Tomcat memory leaks

2010-07-29 Thread Arjen Knibbe
) object);
}

return false;
}

/**
 * Clear a collection recursively.
 * @param info for logging purposes.
 * @param iterable the Collection to be cleared.
 * @return false.
 */
private boolean clearIterableRecursive(String info, Iterable iterable)
{
Vector goners = new Vector();
Iterator iterator = iterable.iterator();

// Special treatment for Collections
// in case the Iterator cannot remove
// but the Collection itself can.
if (iterable instanceof Collection)
{
Collection collection = (Collection) iterable;

for (Object key: collection)
{
if (clearRecursive(info, key))
{
goners.add(key);
}
}
for (Object goner: goners.toArray())
{
System.out.println(info + : removed key referring
ClassLoader from Collection);
collection.remove(goner);
}
return false;
}

while (iterator.hasNext())
{
if (clearRecursive(info, iterator.next()))
{
iterator.remove();
}
}

return false;
}

/**
 * Clear a map recursively.
 * @param info for logging purposes.
 * @param map the Map to be cleared.
 * @return false.
 */
private boolean clearMapRecursive(final String info, final MapObject,
Object map)
{
Vector goners = new Vector();
Object value;
for (Object key: map.keySet())
{
if (clearRecursive(info, key))
{
goners.add(key);
}
else
{
value = map.get(key);
if (clearRecursive(info, value))
{
try
{
map.put(key, null);
System.out.println(info + : removed value referring
ClassLoader from Map);
}
catch (NullPointerException n)
{
goners.add(key);
}
}
}
}
for (Object goner: goners.toArray())
{
System.out.println(info + : removed key referring ClassLoader
from Map);
map.remove(goner);
}

return false;
}

Hope you 'll enjoy

Arjen
-- 
View this message in context: 
http://old.nabble.com/More-sources-of-Tomcat-memory-leaks-tp29264214p29297364.html
Sent from the Tomcat - Dev mailing list archive at Nabble.com.


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



Re: More sources of Tomcat memory leaks

2010-07-29 Thread Rainer Jung

On 29.07.2010 17:00, Arjen Knibbe wrote:

I searched for an upgrading to Tomcat 7 manual in the Tomcat documentation
to check if the new JreMemoryLeakPreventionListener is mentioned, but I
could not find any guidelines for upgrading...


There is some info about major version differences at

http://tomcat.apache.org/migration.html

which is not below the TC 7 docs, so it's common people don't find it :)

Regards,

Rainer

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



Re: More sources of Tomcat memory leaks

2010-07-29 Thread Sylvain Laurent
 containsKey can throw ClassCastException
// So, use the surest way
for (Object item: seen)
{
if (item == seen)
{
return false;
}
}
seen.add(object);
 
if (object instanceof Map)
{
return clearMapRecursive(info, (MapObject, Object) object);
}
else if (object instanceof Iterable)
{
return clearIterableRecursive(info, (Iterable) object);
}
 
return false;
}
 
/**
 * Clear a collection recursively.
 * @param info for logging purposes.
 * @param iterable the Collection to be cleared.
 * @return false.
 */
private boolean clearIterableRecursive(String info, Iterable iterable)
{
Vector goners = new Vector();
Iterator iterator = iterable.iterator();
 
// Special treatment for Collections
// in case the Iterator cannot remove
// but the Collection itself can.
if (iterable instanceof Collection)
{
Collection collection = (Collection) iterable;
 
for (Object key: collection)
{
if (clearRecursive(info, key))
{
goners.add(key);
}
}
for (Object goner: goners.toArray())
{
System.out.println(info + : removed key referring
 ClassLoader from Collection);
collection.remove(goner);
}
return false;
}
 
while (iterator.hasNext())
{
if (clearRecursive(info, iterator.next()))
{
iterator.remove();
}
}
 
return false;
}
 
/**
 * Clear a map recursively.
 * @param info for logging purposes.
 * @param map the Map to be cleared.
 * @return false.
 */
private boolean clearMapRecursive(final String info, final MapObject,
 Object map)
{
Vector goners = new Vector();
Object value;
for (Object key: map.keySet())
{
if (clearRecursive(info, key))
{
goners.add(key);
}
else
{
value = map.get(key);
if (clearRecursive(info, value))
{
try
{
map.put(key, null);
System.out.println(info + : removed value referring
 ClassLoader from Map);
}
catch (NullPointerException n)
{
goners.add(key);
}
}
}
}
for (Object goner: goners.toArray())
{
System.out.println(info + : removed key referring ClassLoader
 from Map);
map.remove(goner);
}
 
return false;
}
 
 Hope you 'll enjoy
 
 Arjen
 -- 
 View this message in context: 
 http://old.nabble.com/More-sources-of-Tomcat-memory-leaks-tp29264214p29297364.html
 Sent from the Tomcat - Dev mailing list archive at Nabble.com.
 
 
 -
 To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
 For additional commands, e-mail: dev-h...@tomcat.apache.org
 


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



Re: More sources of Tomcat memory leaks

2010-07-27 Thread Mark Thomas
On 26/07/2010 09:16, Arjen Knibbe wrote:
 
 After being plaged by PermGen space OutOfMemoryErrors I came across an 
 http://java.dzone.com/articles/memory-leak-protection-tomcat interview with
 Mark Thomas  announcing the solution for these kinds of memory leaks. I
 upgraded Tomcat 6.0.26 on Solaris 5.8 machine and repeatedly deployed and
 undeployed my applications. However, the problem remained. After many weeks,
 I think I got it:

Many, many thanks for your efforts and for writing this up. This looks
great.

Please could you create a Bugzilla entry (against Tomact 7) for each
issue you identified so that this valuable work doesn't get forgotten about?

95% of the work should just be a copy and paste.

Again, many thanks.

Mark

PS How do you fancy trying to fix some of these issues?


 Besides the enhanced WebappClassLoader the new Tomcat uses a Listener
 org.apache.catalina.core.JreMemoryLeakPreventionListener, that has to be
 included in the server.xml file. By upgrading, I missed that.
 
 The class javax.security.auth.Policy has a static member contextClassLoader
 that can refer to the WebappClassLoader.
 from jhat:
 h3Static reference from
 javax.security.auth.Policy.contextClassLoadersmall (from 
 ../object/0xdc035580 class javax.security.auth.Policy) /small :/h3--gt; 
 ../object/0xeb5a84a0 org.apache.catalina.loader.webappclassloa...@0xeb5a84a0
 (157 bytes) 
 br
 
 The class sun.rmi.server.LoaderHander has a static member LoaderTable that
 can contain the WebappClassLoader when using RMI.
 From jhat:
 h3Static reference from sun.rmi.server.LoaderHandler.loaderTablesmall
 (from  ../object/0xdbf2b258 class sun.rmi.server.LoaderHandler) /small
 :/h3--gt;  ../object/0xeb7b52d0 java.util.hash...@0xeb7b52d0 (40 bytes) 
 
  (field table:)br
 --gt;  ../object/0xeb7b52f8 [Ljava.util.HashMap$Entry;@0xeb7b52f8 (40
 bytes) 
  (Element 0 of [Ljava.util.HashMap$Entry;@0xeb7b52f8:)br
 --gt;  ../object/0xeb7b5388 java.util.hashmap$en...@0xeb7b5388 (24 bytes) 
  (field key:)br
 --gt;  ../object/0xeb7b53a0
 sun.rmi.server.loaderhandler$loader...@0xeb7b53a0 (20 bytes) 
  (field parent:)br
 --gt;  ../object/0xeb5a84a0
 org.apache.catalina.loader.webappclassloa...@0xeb5a84a0 (157 bytes) 
 br
 
 The clearReferencesThreadLocals() method of WebappClassLoader clears two
 Thread tables from references to the WebappClassLoader. When using axis, the
 tables can have a HashMap as key, which contains (possibly after many nested
 HashMaps) a class that was loaded by the WebappClassLoader.
 From jhat:
 h3Static reference from org.apache.catalina.ServerFactory.serversmall
 (from  ../object/0xdba00178 class org.apache.catalina.ServerFactory)
 /small :/h3--gt;  ../object/0xeb400668
 org.apache.catalina.core.standardser...@0xeb400668 (67 bytes) 
  (field services:)br
 --gt;  ../object/0xeb4b4178 [Lorg.apache.catalina.Service;@0xeb4b4178 (12
 bytes) 
  (Element 0 of [Lorg.apache.catalina.Service;@0xeb4b4178:)br
 --gt;  ../object/0xeb4b4188
 org.apache.catalina.core.standardserv...@0xeb4b4188 (62 bytes) 
  (field container:)br
 --gt;  ../object/0xeb4b42c8
 org.apache.catalina.core.standardeng...@0xeb4b42c8 (129 bytes) 
  (field thread:)br
 --gt;  ../object/0xeb58b6e0 java.lang.thr...@0xeb58b6e0 (104 bytes) 
  (field threadLocals:)br
 --gt;  ../object/0xeb58b800 java.lang.threadlocal$threadlocal...@0xeb58b800
 (20 bytes) 
  (field table:)br
 --gt;  ../object/0xeb58b818
 [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;@0xeb58b818 (72 bytes) 
  (Element 8 of
 [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;@0xeb58b818:)br
 --gt;  ../object/0xeb58b908
 java.lang.threadlocal$threadlocalmap$en...@0xeb58b908 (28 bytes) 
  (field value:)br
 
 --gt;  ../object/0xeb58b928 java.util.hash...@0xeb58b928 (40 bytes) 
  (field table:)br
 --gt;  ../object/0xeb58b950 [Ljava.util.HashMap$Entry;@0xeb58b950 (72
 bytes) 
  (Element 0 of [Ljava.util.HashMap$Entry;@0xeb58b950:)br
 --gt;  ../object/0xeb58bb40 java.util.hashmap$en...@0xeb58bb40 (24 bytes) 
 
  (field key:)br
 --gt;  ../object/0xdbe798a0 class org.apache.axis.types.Notation (84 bytes) 
  (??:)br
 --gt;  ../object/0xeb5a84a0
 org.apache.catalina.loader.webappclassloa...@0xeb5a84a0 (157 bytes) 
 br
 
 Suppose there is an web application A that uses a database and registers a
 Driver with the java.sql.DriverManager, and a web application B that doesn't
 use a database but has a jar file in its WEB-INF/lib directory that contains
 the same Driver. Suppose you unload webapplication B.
 Running the org.apache.catalina.loader.JdbcLeakPrevention class will
 actually register the Driver and leave it loaded! The cause is the way the
 DriverManager checks whether a ClassLoader has permission to load the
 Driver. It does that by calling ClassForName with the ClassLoader, which
 will load the class if the class has not been loaded by that ClassLoader.
 And loading a Driver triggers the Driver to register itself.
 Seems that the loop in org.apache.catalina.loader.JdbcLeakPrevention has to
 be run twice.
 
 I 

More sources of Tomcat memory leaks

2010-07-26 Thread Arjen Knibbe
, clearing all deep references to the WebappClassLoader./li
/ul
After that, my classes were unloaded after undeploy.

Arjen
-- 
View this message in context: 
http://old.nabble.com/More-sources-of-Tomcat-memory-leaks-tp29264214p29264214.html
Sent from the Tomcat - Dev mailing list archive at Nabble.com.


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