異常信息##
2011-9-1 0:15:11 org.apache.catalina.startup.Catalina start
信息: Server startup in 35866 ms
2011-9-1 2:05:43 org.apache.coyote.http11.Http11Protocol pause
信息: Pausing Coyote HTTP/1.1 on http-8080
2011-9-1 2:05:44 org.apache.catalina.core.StandardService stop
信息: Stopping service Catalina
2011-9-1 2:05:44 org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
嚴重: The web application [] registered the JDBC 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.
2011-9-1 2:05:45 org.apache.coyote.http11.Http11Protocol destroy
信息: Stopping Coyote HTTP/1.1 on http-8080
一個web應(yīng)用程序注冊的JBDC驅(qū)動程序[com.mysql.jdbc.Driver],但Web應(yīng)用程序時停止時未能注銷逸寓。為了防止內(nèi)存泄漏,JDBC驅(qū)動程序已被強行注冊。
解決辦法##
使用Sping org.apache.commons.dbcp.BasicDataSource 配置數(shù)據(jù)源時警告:
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.
問題是tomcat的版本問題殉簸,tomcat新檢測機制導致的這個問題,換版本可以解決問題存皂,但不建議這么做档叔,租用服務(wù)器不是你說換就換的。
其實問題根源是BasicDataSource芋膘,BasicDataSource類close()的一個Bug鳞青。
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.
繼承org.apache.commons.dbcp.BasicDataSource 重寫close():
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.commons.dbcp.BasicDataSource;
public class FixedBasicDataSource extends BasicDataSource {
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
}
@Override
public synchronized void close() throws SQLException {
// 手動注銷
DriverManager.deregisterDriver(DriverManager.getDriver(url));
super.close();
}
}
如果你不知道url,那就這樣:
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
// 手動注銷
DriverManager.deregisterDriver(driver);
Logger.getLogger(this.class.getName()).log(Level.INFO,String.format("deregistering jdbc driver: %s",driver), driver);
} catch (SQLException e) {
Logger.getLogger(this.class.getName()).log(Level.SEVERE,String.format("Error deregistering driver %s",driver), e);
}
}
然后用 FixedBasicDataSource 替換spring配置文件中的數(shù)據(jù)源bean的class【我用的c3p0的數(shù)據(jù)庫連接池的包】为朋。