使用泄漏的 SSLSocketImpl 分析堆转储

问题描述 投票:0回答:3

我有一个在 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
 对象也没有被清理?

谢谢!

java amazon-web-services memory-leaks heap-dump
3个回答
3
投票
这可能是因为未设置 SSL 会话缓存大小,默认情况下该大小是无限的,最终可能会消耗大量堆空间。设置 javax.net.ssl.sessionCacheSize = 1000 应该有所帮助。


3
投票
我想我也遇到过这个问题。在对 MAT 进行了一些修改之后,我能够找出发生的情况的根本原因,或者至少阻止 G1GC 在永久空间上执行完整的 GC。这是我正在看的垫子图:

我的应用程序是一个简单的 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

一旦我这样做了,我的长期空间大小就再也没有增长,而 g1_old_space 将以与长期空间大小相同的速度增长,但是我的 G1 能够比长期更有效地清理 g1_old_space,所以长时间的应用程序暂停消失了,G1 尊重了我的

-XX :MaxGCPauseMillis


    

请问您采取了哪些措施来解决?


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.