当我运行我的web应用程序时,我得到了这个消息。它运行得很好,但我在关机时收到以下消息。
严重: web应用程序注册了JBDC驱动程序oracle.jdbc.driver.OracleDriver,但在web应用程序停止时未能将其注销。为了防止内存泄漏,JDBC驱动程序已被强制注销。
感谢您的帮助。
发布于 2010-07-24 01:01:53
从版本6.0.24开始,Tomcat附带了memory leak detection功能,当webapp的/WEB-INF/lib
中有一个与JDBC 4.0兼容的驱动程序时,会导致这种警告消息,该驱动程序在webapp的启动过程中使用ServiceLoader
API自动registers自己,但在webapp的关闭过程中没有自动deregister自己。此消息纯粹是非正式的,Tomcat已经采取了相应的内存泄漏预防措施。
你能做什么?
/WEB-INF/lib
中删除JDBC驱动程序,而只能在服务器的/lib
中删除。如果您仍将其保留在webapp的/WEB-INF/lib
中,则应使用ServletContextListener
.手动注册和取消注册
期间OutOfMemoryError
issues背后的主要原因之一
/lib
文件夹中,并使用连接池数据源来管理该驱动程序。请注意,Tomcat的内置DBCP不能在关闭时正确注销驱动程序。另请参阅bug DBCP-322,它被关闭为WONTFIX。您更愿意用另一个比DBCP做得更好的连接池来替换DBCP。例如,HikariCP或Tomcat JDBC Pool.发布于 2011-03-16 01:20:49
在servlet上下文侦听器contextDestroyed()方法中,手动注销驱动程序:
// This manually deregisters JDBC driver, which prevents Tomcat 7 from complaining about memory leaks wrto this class
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
LOG.log(Level.INFO, String.format("deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
LOG.log(Level.SEVERE, String.format("Error deregistering driver %s", driver), e);
}
}
发布于 2014-05-28 20:56:56
尽管Tomcat确实会强制取消JDBC驱动程序的注册,但最好还是清理webapp在上下文销毁时创建的所有资源,以防您移动到另一个servlet容器,该容器不会执行Tomcat所做的内存泄漏预防检查。
然而,全面注销驱动程序的方法是危险的。由DriverManager.getDrivers()
方法返回的一些驱动程序可能已由父ClassLoader (即servlet容器的类加载器)加载,而不是webapp上下文的ClassLoader加载(例如,它们可能在容器的lib文件夹中,而不是webapp的ClassLoader文件夹中,因此在整个容器中共享)。取消这些注册将影响任何其他可能正在使用它们的the应用程序(甚至是容器本身)。
因此,在取消注册之前,应该检查每个驱动程序的ClassLoader是否为webapp应用程序的ClassLoader。因此,在ContextListener的contextDestroyed()方法中:
public final void contextDestroyed(ServletContextEvent sce) {
// ... First close any background tasks which may be using the DB ...
// ... Then close any DB connection pools ...
// Now deregister JDBC drivers in this context's ClassLoader:
// Get the webapp's ClassLoader
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// Loop through all drivers
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (driver.getClass().getClassLoader() == cl) {
// This driver was registered by the webapp's ClassLoader, so deregister it:
try {
log.info("Deregistering JDBC driver {}", driver);
DriverManager.deregisterDriver(driver);
} catch (SQLException ex) {
log.error("Error deregistering JDBC driver {}", driver, ex);
}
} else {
// driver was not registered by the webapp's ClassLoader and may be in use elsewhere
log.trace("Not deregistering JDBC driver {} as it does not belong to this webapp's ClassLoader", driver);
}
}
}
https://stackoverflow.com/questions/3320400
复制相似问题