【问题标题】:Analyzing a heap dump with leaked SSLSocketImpl使用泄露的 SSLSocketImpl 分析堆转储
【发布时间】:2017-04-21 08:03:57
【问题描述】:

我有一个在 Amazon EC2 上运行的应用程序(使用多个 AWS 产品,例如 S3、DynamoDB 等)并且存在内存泄漏。我收集了一些堆转储并通过 Eclipse 的内存分析器工具运行它们,该工具将数百个 sun.security.ssl.SSLSocketImpl 实例(占用数十 MB 内存)确定为可能的泄漏。

但我无法弄清楚为什么这些 SSLSocketImpl 对象没有被处理掉。

转储中SSLSocketImpl 的大多数实例都有两个引用,一个来自java.lang.ref.Finalizer,一个来自com.amazonaws.internal.SdkSSLSocket。我的堆转储中的终结器线程报告为空闲,没有等待终结的对象。但是引用了泄露的SSLSocketImpl 对象的com.amazonaws.internal.SdkSSLSocket 对象似乎已被清除。至少,我在堆转储中找不到它们(MAT 中的 Dominator 视图)。

我是分析 Java 堆转储的新手。接下来我应该寻找什么?如果亚马逊的SdkSSLSocket 对象确实被清理了,为什么SSLSocketImpl 对象没有被清理?

谢谢!

【问题讨论】:

  • 你找到什么了吗?
  • 从来没有找到这个问题的根源。它已经被搁置了几个月,因为部署新实例具有使内存泄漏成为非问题的副作用。
  • 您使用了哪些 EC2 实例?

标签: java amazon-web-services memory-leaks heap-dump


【解决方案1】:

我想我也遇到了这个问题。在稍微弄乱了 MAT 之后,我能够从根本上解决正在发生的事情,或者至少阻止 G1GC 在永久空间上执行完整的 GC。这是我正在查看的垫图:

我的应用程序是一个简单的 Spring Boot 响应式 http 服务器,它代理了合理数量的数据库读取调用。我在 K8s 上的 docker 容器中运行单个 CPU,内存大约 4GB。我将其翻倍至 8GB 内存,但仍然发现问题。

我不相信这是内存泄漏,因为我可以观察到 Full GC 能够清理永久空间,这需要一段时间。

我相信 JDBC 正在做的是,当 TCP 连接被Abandoned 时,它们被归入一个名为 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

【讨论】:

    【解决方案2】:

    这可能是因为没有设置 SSL 会话缓存大小,默认情况下它是无限的,最终可能会消耗大量堆空间。设置 javax.net.ssl.sessionCacheSize = 1000 应该会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      • 2023-03-19
      • 2017-06-18
      • 2021-11-06
      • 2013-02-14
      • 1970-01-01
      相关资源
      最近更新 更多