天天看點

tomcat的一個常見錯誤

現象:

上次同僚在熱部署應用到liferay伺服器上時,遇到了以下錯誤:

Sep 21, 2012 3:19:06 AM org.apache.catalina.startup.HostConfig deployDirectory 

INFO: Deploying web application directory /home/portal/liferay-container-1.0.0-SNAPSHOT/standalone/liferay-portal/community-edition-liferay-portal-tomcat-6.1.0/liferay-portal-6.1.0-ce-ga1/tomcat-7.0.23/webapps/paas_integration_portlet 

Sep 21, 2012 3:19:06 AM org.apache.catalina.core.StandardContext startInternal 

SEVERE: Error listenerStart 

SEVERE: Context [/paas_integration_portlet] startup failed due to previous errors 

Sep 21, 2012 3:19:06 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks 

SEVERE: The web application [/paas_integration_portlet] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@3e043340]) and a value of type [java.lang.Class] (value [class oracle.sql.AnyDataFactory]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. 

SEVERE: The web application [/paas_integration_portlet] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@5c0ce8f]) and a value of type [java.lang.Class] (value [class oracle.sql.TypeDescriptorFactory]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. 

Sep 21, 2012 3:19:06 AM org.apache.coyote.AbstractProtocol start 

INFO: Starting ProtocolHandler ["http-bio-8080"] 

INFO: Starting ProtocolHandler ["ajp-bio-8009"] 

Sep 21, 2012 3:19:06 AM org.apache.catalina.startup.Catalina start 

INFO: Server startup in 37724 ms 

基于我的以前經驗,這是"類加載器洩露“的問題,具體細節參見我的以下郵件回複:

<b>Reason:</b><b></b>

<b></b>

This is very common in Tomcat .

We all know (1) ThreadLocal is used for holding variables per thread.

                         (2) Tomcat supports multi-threads.

                        (3) The default GC mechanism for tomcat is “object reference”

So the process is ,when we redeploy a portlet ,then the WebClassloader will load all the necessary classes and jars which required by this portlet ,and the threadlocal is used for identifying the thread . But when we destroy the portlet(redeploy or remove) ,though the portlet is removed ,but the threadlocal  value didn’t remove ,(which means the object reference number still &gt;0) ,so the classes loaded by WebappClassLoader can’t not be gc , that’s a very famous topic  “Classloader leak”

My highlighted part is my understanding to this problem and it can explains what Judith has highlighted .

<b>Solution:</b>

“Classloader leak” issue happened since the first version of tomcat ,and it always a challenging work , as I know ,since tomcat 7 (because our Liferay 6.1 based on tomcat 7) has added some detection mechanism to detect the classloader leak issue ,that’s why it report “SEVERE”   ,if you familiar with tomcat 5 or 6 ,it just shutdown without any useful information.

Up to now just as I know ,we have no solution about it ,maybe we need to new version of tomcat to fix it .  If often meet with it ,I suggest we re-start the liferay.

<b>Referenced Articles:</b>

<a target="_blank" href="http://wiki.apache.org/tomcat/MemoryLeakProtection#customThreadLocal">http://wiki.apache.org/tomcat/MemoryLeakProtection#customThreadLocal</a>

<a target="_blank" href="https://issues.apache.org/bugzilla/show_bug.cgi?id=49159">https://issues.apache.org/bugzilla/show_bug.cgi?id=49159</a>

<a target="_blank" href="http://www.javacodegeeks.com/2012/05/threading-stories-threadlocal-in-web.html">http://www.javacodegeeks.com/2012/05/threading-stories-threadlocal-in-web.html</a>

Charles

本文轉自 charles_wang888 51CTO部落格,原文連結:http://blog.51cto.com/supercharles888/1004323,如需轉載請自行聯系原作者