如何在堆转储中的异常实例没有入站引用的情况下调试内存泄漏?

Wal*_*ndt 6 java android memory-leaks

我一直在尝试诊断我正在编写的Android应用程序中的内存泄漏.我有一个堆转储加载到Eclipse中,但我看到的结果非常好奇.堆中有大约20,000个异常实例(特别是来自UnboundID LDAP库的LDAPException),没有入站引用.

也就是说,它们出现在支配者树的根部.OQL SELECT objects e FROM com.unboundid.ldap.sdk.LDAPException e WHERE (inbounds(e).length = 0)返回超过20,000个结果,总计几乎所有堆.然而,GC在堆转储之前运行,我可以看到它在执行泄漏代码期间反复运行在控制台中.如果这些实例没有入站参考,那么可以让它们保持活力?

我也尝试过"最短的GC路径"查询.它显示了一个保留2个实例的LDAPConnectionReader行,以及LDAPException @ <addr> unknown具有各种十六进制地址的~20k 行.

更新:自发布以来我没有时间进一步诊断,我发布的奖金在我可能会结束之前就已经结束了.我现在尽可能地奖励它,以免浪费点数.感谢所有关注此事的人!我将稍后回来并再次更新进一步诊断的结果,当生活稍微忙碌时.

Ron*_*onU 4

无论是否抛出这些异常,就内存使用而言,该细节几乎无关紧要。

虽然您希望在堆转储中查看谁持有引用,但由于某种原因,您无法看到这一点。我想知道本机代码是否会在堆转储工具中正确符号化?

无论哪种方式,作为新的尝试,我建议不要调试抛出这些异常的点,而是调试它们的创建位置。在类和/或其所有构造函数上放置断点。理想情况下,您只需从堆转储引用中获取此信息,但如果您可以看到谁在重复构建这些对象,那么它仍然可能提供有用的信息......我猜它们来自同一个地方。