当我运行我的web应用程序时,我得到这条消息。它运行良好,但我在关机期间收到这条消息。
严重:web应用程序注册了JBDC驱动程序[oracle.jdbc.driver. exe]。但是当web应用程序停止时,无法注销它。为了防止内存泄漏,JDBC驱动程序已被强制注销。
感谢任何帮助。
当我运行我的web应用程序时,我得到这条消息。它运行良好,但我在关机期间收到这条消息。
严重:web应用程序注册了JBDC驱动程序[oracle.jdbc.driver. exe]。但是当web应用程序停止时,无法注销它。为了防止内存泄漏,JDBC驱动程序已被强制注销。
感谢任何帮助。
当前回答
我将补充一些我在Spring论坛上发现的东西。如果您将JDBC驱动程序jar移到tomcat lib文件夹,而不是与webapp一起部署它,则警告似乎消失了。我可以确定这对我很有效
http://forum.springsource.org/showthread.php?87335-Failure-to-unregister-the-MySQL-JDBC-Driver&p=334883#post334883
其他回答
这个错误发生在我使用JTDS Driver 1.3.0 (SQL Server)的Grails应用程序中。问题是SQL Server登录错误。解决这个问题后(在SQL Server),我的应用程序被正确部署在Tomcat。提示:我在stacktrace.log中看到了错误
从版本6.0.24开始,Tomcat附带了内存泄漏检测特性,当web应用程序的/WEB-INF/lib中有JDBC 4.0兼容的驱动程序时,该驱动程序会在web应用程序启动期间使用ServiceLoader API自动注册自己,但在web应用程序关闭期间不会自动注销自己,这会导致此类警告消息。此消息完全是非正式的,Tomcat已经采取了相应的内存泄漏预防操作。
你能做什么?
Ignore those warnings. Tomcat is doing its job right. The actual bug is in someone else's code (the JDBC driver in question), not in yours. Be happy that Tomcat did its job properly and wait until the JDBC driver vendor get it fixed so that you can upgrade the driver. On the other hand, you aren't supposed to drop a JDBC driver in webapp's /WEB-INF/lib, but only in server's /lib. If you still keep it in webapp's /WEB-INF/lib, then you should manually register and deregister it using a ServletContextListener. Downgrade to Tomcat 6.0.23 or older so that you will not be bothered with those warnings. But it will silently keep leaking memory. Not sure if that's good to know after all. Those kind of memory leaks are one of the major causes behind OutOfMemoryError issues during Tomcat hotdeployments. Move the JDBC driver to Tomcat's /lib folder and have a connection pooled datasource to manage the driver. Note that Tomcat's builtin DBCP does not deregister drivers properly on close. See also bug DBCP-322 which is closed as WONTFIX. You would rather like to replace DBCP by another connection pool which is doing its job better then DBCP. For example HikariCP or perhaps Tomcat JDBC Pool.
尽管Tomcat会强制注销JDBC驱动程序,但在上下文破坏时清理webapp创建的所有资源是一个很好的实践,以防您移动到另一个servlet容器,该容器不像Tomcat那样执行内存泄漏预防检查。
但是,全面取消司机登记的方法是危险的。DriverManager.getDrivers()方法返回的一些驱动程序可能是由父类加载器(即servlet容器的类加载器)加载的,而不是webapp上下文的类加载器(例如,它们可能在容器的lib文件夹中,而不是webapp的,因此在整个容器中共享)。注销这些将会影响其他可能使用它们的web应用程序(甚至容器本身)。
因此,在取消注册之前,应该检查每个驱动程序的ClassLoader是否是web应用程序的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);
}
}
}
如果您从Maven构建的war中获得此消息,则将JDBC驱动程序的作用域更改为已提供,并将其副本放在lib目录中。是这样的:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
<!-- put a copy in /usr/share/tomcat7/lib -->
<scope>provided</scope>
</dependency>
我在AWS上部署Grails应用程序时遇到过这个问题。这是JDBC默认驱动程序的问题。H2驱动。 正如你在数据源中看到的那样。配置文件夹中的Groovy。如下图所示:
dataSource {
pooled = true
jmxExport = true
driverClassName = "org.h2.Driver" // make this one comment
username = "sa"
password = ""
}
注释那些提到org.h2的行。数据源中的驱动程序。Groovy文件,如果您没有使用该数据库。 否则,您必须下载数据库jar文件。
谢谢。