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

标签 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 在堆转储之前运行,我可以看到它在执行泄漏代码期间在控制台中反复运行。如果这些实例没有入站引用,是什么让它们保持 Activity 状态?

我还尝试执行“到 GC 的最短路径”查询。它显示一个 LDAPConnectionReader 行保留 2 个实例,并且 ~20k LDAPException @ <addr> unknown具有各种十六进制地址的行。

更新:自发布以来我还没有时间进一步诊断,而且我发布的赏金可能会提前结束。我现在尽可能地奖励它,以免浪费积分。感谢所有调查此事的人!等生活稍微不那么忙碌时,我会回来再次更新进一步诊断的结果。

最佳答案

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

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

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

关于java - 如何调试堆转储中的异常实例没有入站引用的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3631558/

相关文章:

java - Cipher.unwrap() key 长度 Sun - BouncyCaSTLe 兼容性

android - TextChanged 监听器

java - audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT) 不起作用

python - 使用 SQLite 了解 PonyORM 中的内存消耗

java - 如何在 Windows 上远程启动 Tomcat

java - 使用 Eclipse、Tomcat 和 Jetspeed 热部署开发更改

Android 可访问性对讲说出 fragment 的标题

ios - AVMutableComposition 内存泄漏

c++ - Live555 客户端流媒体内存泄漏

java - 编码字符串在java中不能正常工作