我有一个在 Amazon EC2 上运行的应用程序(使用多种 AWS 产品,例如 S3、DynamoDB 等)并且存在内存泄漏。我收集了一些堆转储并通过 Eclipse 的内存分析器工具运行它们,该工具将数百个
sun.security.ssl.SSLSocketImpl
实例(占用了数十 MB 内存)确定为可能的泄漏。
我很难弄清楚为什么这些SSLSocketImpl
物体还没有被处理掉。转储中的
SSLSocketImpl
的大多数实例都有两个引用,一个来自
java.lang.ref.Finalizer
,另一个来自
com.amazonaws.internal.SdkSSLSocket
。我的堆转储中的终结器线程报告为空闲,没有对象等待终结。但是引用了泄漏的
com.amazonaws.internal.SdkSSLSocket
对象的
SSLSocketImpl
对象似乎已被清理。至少,我在堆转储中找不到它们(MAT 中的 Dominator 视图)。我是分析 Java 堆转储的新手。接下来我应该寻找什么?如果 Amazon
SdkSSLSocket
对象确实已被清理,为什么
SSLSocketImpl
对象也没有被清理?谢谢!
我的应用程序是一个简单的 Spring boot 反应式 http 服务器,它代理合理数量的数据库读取调用。我在 K8s 上的 docker 容器中运行单个 CPU,内存约为 4GB。我将内存增加了一倍,达到 8GB,但问题仍然存在。
我不相信这是内存泄漏,因为我可以观察到完整的 GC 能够清理永久空间,这只需要一段时间。
我认为 JDBC 正在做的是,当 TCP 连接被“放弃”时,它们被降级到一个名为“AbandonedConnectionCleanupThread”的线程。
So what the solution turned out to be was just giving the JVM an extra CPU to service the AbandonedConnectionCleanupThread
。
-XX :MaxGCPauseMillis
请问您采取了哪些措施来解决?