Jdbc 和 Tomcat 疑似内存泄漏

Suspected memory leak with Jdbc and Tomcat

我的 tomcat 日志中有这些消息:

" org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc Web 应用程序注册了 JBDC 驱动程序 [com.mysql.jdbc.Driver],但在 Web 应用程序停止时无法注销它。为防止内存泄漏,已强制注销 JDBC 驱动程序。"

"org.apache.catalina.loader.WebappClassLoaderclearReferencesThreads 严重:Web 应用程序似乎启动了一个名为 [pool-820-thread-1] 的线程,但未能停止它。这很可能会造成内存泄漏。"

实际上我的 java 项目中有一个 JDBC 驱动程序 (.jar),我总是将其作为 .war 部署在 tomcat 服务器上(意思是驱动程序始终在 war/libs 目录中)。

搜索后,我找到了一个很好的答案 here 但不幸的是,我还不能对 Whosebug 发表评论以获取有关已接受答案的更多详细信息。

这是我的问题: - 答案是建议从 war/libs 目录中完全删除 .jar 吗? - 如果是,我应该把它放在哪里?因为我不知道如何完全摆脱 .jar 并且仍然能够在本地对数据库进行测试。

请指教。

从 Tomcat 6.0 开始,有一个功能可以检测 classloader 内存泄漏。阅读更多 here。 tomcat 的上述消息仅供参考,tomcat 已经采取足够的措施通过注销 Driver 来避免 classloader 泄漏。

如您正确指出的那样,要防止出现这种情况,您可以将 jar 完全移动到 tomcat 的 lib 文件夹,这样它就不会受到应用程序上下文重新加载的影响。或者您可以显式调用 DriverManager.deregister(driver)。 (阅读here

了解更多关于 ClassLoader 泄漏的信息 (here)

要了解为什么建议将其从应用程序 WEB_INF/lib 移至 tomcat lib,您可以阅读更多内容 here.

根据评论中的查询进行编辑

不,不建议使用多个 jar,因为它会导致 classcastexception。每个 class 由 class 名称和 classloader 的组合标识。通过示例查看 this 以获得更清晰的理解。

根据我的说法,更好的方法是编写一个 servlet 上下文侦听器,并在上下文被销毁时显式注销您的驱动程序。这样您就可以将 jdbc 驱动程序保留在 web-inf/lib 中,而无需将其移动到 tomcat/lib.

即使您将 jar 保存在多个位置,根据 tomcat 遵循的 classloader 层次结构,这与 java 委派模型不同(更多信息 here) , tomcat 将首先拿起您 web-inf/lib 中的罐子。