许多在堆中带有 finalize() 的对象,即 PgConnection

问题描述

在分析我的应用程序的堆转储时,我注意到 java.lang.red.Finalizer 类的 1478 个实例。 501 个引用 org.postgresql.jdbc.PgConnection 类和另一个 501 sun.security.ssl.SSLSocketImpl。 Finalizer类的队列长度为0。

堆转储所属的应用程序的正常运行时间为 185 小时。

db连接池的配置如下:

  • 最大池大小 - 5
  • 最长使用时间 - 30 分钟

DB 连接在一段时间内未使用时会过期,并在需要时创建新连接。到现在为止还挺好。应用程序上的工作负载会随着时间的推移而变化。此外,数据库大小的打开连接数看起来不错 - 5。

当我比较不同正常运行时间后堆转储中 PgConnection 实例的数量时,我发现它增加了,并且 Finalizer 类中的队列长度始终为 0。

我在本地做了一个测试。只需将池中的最大生命时间设置为一个非常低的数字并等待 2 小时。 PgConnection 实例的数量从 5 个增加到 16 个。所有陈旧的连接都被正确关闭(在 PgConnection#close() 中有一个断点)。 Finalizer 中的队列大小为 0。使用 VisualVM 执行 full GC 后,PgConnections 的数量减少到 5,并调用了 PgConnection#finalize() 方法(也在此处设置了断点)。

GC 不会自动删除具有重载 finalize() 方法(即 PgConnection)的对象是否是预期/正常行为?我知道在删除此类对象时无法保证。但是,在这种情况下,自应用程序启动以来,这些对象似乎都没有被删除。也许我错过了 GC 配置中的某些内容?我在生产环境中设置了 disableExplicitGC 参数,但据我所知,它不会对常规 GC 工作造成任何损害。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)