【问题标题】:How can I find memory leaks with profiler如何使用探查器查找内存泄漏
【发布时间】:2018-05-31 20:44:09
【问题描述】:

我已经转储了大量内存,并发现肯定存在内存泄漏。如果你看截图,你会看到只有一个片段,但有 9 个相同类型的演示者。应该只有一个。当我检查一个演示者实例时,分析器会向我显示对演示者的引用。 这些都是 RxAndroid 方法的回调方法。我正在正确地取消订阅片段的 onDestroyView 中的所有内容。仍然没有清理演示者实例(如您所见)。

所以我想知道如何区分有效的(循环的、内部的)引用,因为对象仍然没有被垃圾回收,所以仍然存在,以及有问题的引用(导致对象没有被清理)。

有人可以指导我如何找出可能发现内存泄漏的位置吗?

这个转储是在触发 GC 之后生成的!

【问题讨论】:

  • 你尝试过 LeakCanary 了吗? github.com/square/leakcanary
  • 我对 LeakCanary 的研究不够深入 - 现在会这样做......
  • 这些对象的Subscriptions 存储在哪里?调用unsubscribe 是不够的,你必须null 删除任何引用。或者,使用onTerminateDetach

标签: android memory-leaks profiling rx-java rx-android


【解决方案1】:

如果您使用内存分析器强制进行垃圾收集,那么您就会知道您看到的其他意外对象正在使用中,因此它们可能是真正的泄漏,而不仅仅是等待收集。 您需要找到 gc root 的路径,这将告诉您阻止其他对象被垃圾收集的对象。

查看此处的“Garbge Collection Roots”部分了解更多信息。 Android 内存分析器会告诉您到达 gc 根目录的最短跳数,但最好只捕获一个 hprof 并使用 Eclipse MAT 之类的东西来查看到 gc 根目录的路径。 Eclipse MAT 甚至可以为您检查泄漏。

【讨论】:

    【解决方案2】:

    您应该尝试使用 Square 的开源库 Leakcanary 来检测内存泄漏。它使您免于做大量的手动工作,例如

    • 使用 hprof 转储
    • 分析 hprof 转储以识别泄漏
    • 查找导致泄漏的参考
    • 修复并重复上述步骤

    我有一篇关于内存泄漏和 Leakcanary 的博客,you can find it here

    【讨论】:

    • Leak Canary 帮助发现了 2 个泄漏点。但它没有检测到第三次泄漏:我使用了 supportFragmentManager 而不是 childFragmentManager。
    猜你喜欢
    • 2015-09-19
    • 2012-02-27
    • 2011-07-05
    • 2017-12-30
    • 2017-11-29
    • 2019-08-20
    • 2014-03-26
    相关资源
    最近更新 更多