【问题标题】:How to track down memory leak - Find living references如何追踪内存泄漏 - 查找活引用
【发布时间】:2011-01-28 00:32:26
【问题描述】:

我有一个相当复杂的应用程序 -

UI Activity 启动一个 Service 并设置 2 路 AIDL 回调,以便两者可以通信。

服务永远运行(除非在 UI Activity 中点击“关闭”按钮)。

问题是当用户退出Activity时,Activity内存没有释放。 - 即使 UI Activity 已关闭,我的应用程序使用的内存量也是相同的。 - 即使 UI Activity 已关闭,堆上仍会显示 mapTiles 和其他 UI 废话。

所以我的猜测是,Service 以某种方式持有对 Activity 的引用。我知道许多关于泄漏活动上下文的文章警告。服务仅通过存储在应用程序范围内的弱引用来引用活动。 (扩展应用程序的类)

有什么方法可以找到具体引用 Activity 的内容吗?支配树显示 mapTiles 和 ListView 布局占用了我所有的内存......但我找不到对保持这些东西保持活力的 Activity 的引用。

另外,如果发生 OutOfMemoryException,有没有办法转储 HPROF 堆转储?

【问题讨论】:

    标签: android service memory-leaks android-context aidl


    【解决方案1】:

    问题是当用户退出 Activity,Activity内存不是 发布。

    Android 中没有“退出活动”。调用 finish() 或按回活动不会从内存中删除活动使用的对象。 Android 本身会在未来的某个随机时间自行处理。

    如果您希望在活动结束时从内存中释放您的对象,您需要自己手动释放它们。

    编辑:可用于查找内存使用情况的类是ActivityManager

    【讨论】:

    • 当我执行菜单 -> 应用程序 -> 运行服务时。它显示 com.myapp 有 15MB。我本来想退出 Activity(后退箭头),然后在电话上搞乱一点,Activity 将被垃圾收集,数字会下降。它永远不会。
    • 该屏幕是特定于服务的。您的活动正在启动一项服务,而该服务就是您使用 15MB 内存所看到的。当您退出活动时,此服务不会停止。它由操作系统处理以根据需要停止。例如,我目前的服务已经运行了 48 小时以上……上次我重新启动手机时。在您的服务代码中,您可以根据需要选择停止/启动此服务。
    • 好的 - 很高兴知道屏幕是特定于服务类的。有任务管理器吗?我如何知道 Activity 使用了多少 RAM?
    • SDK 中有一种方法可以执行此操作。我会看看能不能找到它并更新我的原始帖子。
    【解决方案2】:

    如果持有引用的不是你自己(“通过存储在应用程序范围内的弱引用来引用活动”,你是否为空?我想知道为什么你在服务中引用活动,通常是相反的方式),您是否尝试执行 GC?只要有足够的内存,就不会发生 gc 来将垃圾移走。

    【讨论】:

    • 在 Activity onDestroy 中,我调用 Wea​​kReference.clear() 以确保 Activity Reference 消失。假装它是一个电子邮件应用程序......该服务正在轮询服务器并使用新电子邮件更新本地数据库。然后它说“如果 UI Activity 引用不为空,请告诉他们显示新消息”。
    猜你喜欢
    • 2011-02-15
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多