最近項目中遇見一問題,在開發環境沒有問題的代碼,到了生產環境就會報如下錯誤:
To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
今天開始學習了struts2, 於是下了最新的版本struts2.2.3.1,在使用的過程中總是報錯:A web application created a ThreadLocal with key of type , 盡管出現了這個錯誤,但是並不妨礙程序正常運行, 雖然程序雖然能正常運行,但是看的這個錯誤很是別扭,所以網上搜了一下看看,也就有了下面這篇文章
struts2關於A web application created a ThreadLocal with key of type 異常解決辦法
created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@12c74b9]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@1a34544]) but failed to remove it。。。。
這類問題的解決辦法:
http://confluence.atlassian.com/pages/viewpage.action?pageId=218275753
看看老外的這篇,好像就是在講這個問題,原因大概是說tomcat 6.025之后引入了一種內存泄露的檢查機制,會把不能垃圾收集的對像做日志。
第一種解決辦法:
使用低於6版本的tomcat
第二種解決辦法:
在tomcat的server.xml文件(在tomcat的安裝路徑下的conf文件夾里)中把
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
這個監聽給關了。
就是用<!--。。。-->把下面三句話括起來就可以啦。
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
http://blog.csdn.net/zhuhezan/article/details/6882089
Description
BasicDataSource's method close() doesn't deregister JDBC driver. This causes permgen memory leaks in web server environments, during context reloads. For example, using Tomcat 6.0.26 with Spring, and BasicDataSource declared in Spring context, there is a message printed at web application reload:
SEVERE: A web application registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
I was able to fix it by overriding close method this way:
public class XBasicDataSource extends BasicDataSource { @Override public synchronized void close() throws SQLException { DriverManager.deregisterDriver(DriverManager.getDriver(url)); super.close(); } }
but I think it should be probably the default behavior of BasicDataSource. Or perhaps there should be some flag/setting on BasicDataSource, named "deregisterDriverAtClose" or so.
https://issues.apache.org/jira/browse/DBCP-332
