Spring Boot - 内存泄漏 - H2 数据库 - 不注销驱动程序

Posted

技术标签:

【中文标题】Spring Boot - 内存泄漏 - H2 数据库 - 不注销驱动程序【英文标题】:Spring Boot - Memory Leak - H2 Database - Does not unregister driver 【发布时间】:2020-07-29 21:46:15 【问题描述】:

由于新信息而完全重做:

最初的问题:当多次重新部署一个简单的 Spring Boot 应用程序 (2.2.6) 时,JBoss 用“OutOfMemoryError: Metaspace”杀死了自己

使用堆转储我发现 H2 驱动程序 (1.4.200) 保留引用并导致问题

后来我检查了为什么tomcat没有这样的行为,发现

The web application [killerApp] registered the JDBC driver [org.h2.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 中工作,因为它足够聪明,可以注意到内存泄漏并防止它。 JBoss 不做,遇到麻烦了……

看起来带有 H2 的标准 Spring Boot 应用程序在处理取消注册 H2 驱动程序方面行为不端……至少这是我的收获。

我还发现了这个:GitHub - Spring Boot - Discussion about unregister managed JDBC drivers

现在我不确定,谁在“过错”?

    我,因为我需要正确注销 H2 驱动程序 我是因为我错误配置了 Spring Boot 应用程序 用于保持内部状态的 H2 驱动程序? Spring boot 用于中继 Tomcat 进行整理

最好的,非常感谢

【问题讨论】:

您是否使用过任何类型的分析工具来查看是什么占用了内存? 谢谢!今天我花时间检查了堆转储并发现了问题......即使还不确定,应该如何最好地解决它。问题相应更新 【参考方案1】:

又是一个 MAT 和 OOM 的周末,我现在修复了内存泄漏问题。

首先,我现在在 ContextListener 中手动取消注册从 Spring Boot 启动的 JDBC 驱动程序(从 2.3.0 开始,Spring boot 将自动取消注册 -> https://github.com/spring-projects/spring-boot/issues/21221)。 这解决了第一次内存泄漏。

另一个来自 io.github.classgraph。 destroy 是作为应用程序关闭钩子添加的,仅在 JVM 关闭时执行。 -> 对于一直运行的应用程序服务器来说不是一个好主意。他们修复了它,但 springdoc-openapi-ui / org.webjars:webjars-locator-core 仍在使用带有错误的旧版本。所以我手动增加了类图版本。 这解决了第二次内存泄漏......该死的我从来不想知道这么多关于这些东西的东西(否则我会用 C 编程:D)

问题解决了:)

【讨论】:

以上是关于Spring Boot - 内存泄漏 - H2 数据库 - 不注销驱动程序的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个 Spring Boot 应用程序访问一个 Spring Boot 应用程序的内存 H2 数据库

如何跨多个 Spring Boot 应用程序共享 H2 内存数据库?

在内存数据库中使用 H2 进行 Spring Boot 集成测试

用于与 postgresql 在内存中兼容 h2 的 Spring Boot 属性

内存数据库H2中的Spring Boot在初始化时不会从文件中加载数据

使用 Liquibase 为 Spring Boot 应用程序中的单元测试初始化​​内存 H2