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

3

因为新信息,进行了全面的改写:

  • 初始问题:当多次重新部署简单的Spring Boot应用程序(2.2.6)时,JBoss会出现"OutOfMemoryError: Metaspace"错误。

  • 使用堆转储,我发现H2驱动程序(1.4.200)保留了引用并导致问题enter image description here

  • 之后我检查了为什么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没有这样做,结果遇到了麻烦...

看起来这个标准的Spring Boot应用程序与H2在注销H2驱动程序方面的处理方式有问题...至少这是我的理解。

我另外找到了这个:GitHub - Spring Boot - 有关注销托管JDBC驱动程序的讨论

现在我不确定谁是 "有错" 的人?

  1. 是我,因为我需要正确注销H2驱动程序
  2. 是我,因为我配置Spring Boot应用程序时出了问题
  3. H2驱动程序保持内部状态?
  4. Spring Boot依赖Tomcat整理

最好的情况和非常感谢


1
你使用过任何分析工具来查看是什么占用了内存吗? - James R. Perkins
谢谢!今天我花时间检查了堆转储,并找到了问题……尽管还不确定应该如何最好地解决。相应地更新了问题。 - ben
1个回答

2

与MAT&OOMs度过的又一个周末,我现在已经修复了内存泄漏问题。

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

另一个问题来自于io.github.classgraph。它增加了destroy thing作为应用程序关闭钩子,在JVM关闭时才会执行。-> 这对于一个不断运行的应用程序服务器来说不是一个好主意。他们已经修复了它,但springdoc-openapi-ui/org.webjars:webjars-locator-core仍然使用带有bug的旧版本。所以我手动增加了classgraph版本。这解决了第二个内存泄漏问题...该死的,我从未想过我需要了解这些东西(否则我就会使用C进行编程:D)

问题得到解决 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接