调用完成()确实到活动不明确的内存引用(Calling finish() does not clea

2019-08-07 16:52发布

在我的应用程序的简化版本,我有两个活动,A和B. Actvity A开始B,经过一番工作,B调用完成()。 在大多数设备上使用内存分析工具(Galaxy Nexus的运行4.2的Droid 4运行4.0.4,和Droid 2的运行2.3.4)没有显示出活性B,这是我所期待的痕迹。

但在三星S3运行4.1.1,MAT展示活动B各地对象是,由于路径以下GC根(弱/软引用除外):

Class Name                                                        | Shallow Heap | Retained Heap
-------------------------------------------------------------------------------------------------
com.myCo.myApp.ActivityB  @ 0x42720818                            |          264 |         3,280
|- <Java Local> java.lang.Thread @ 0x4271cf60  Thread-21941 Thread|           80 |        52,264
|- mOuterContext android.app.ContextImpl @ 0x426adf68             |          104 |           784
    |  '- mContext android.media.AudioManager @ 0x428e49a0        |           48 |           152
-------------------------------------------------------------------------------------------------

我每次启动和停止活动B,MAT展示活动B的内存占用的另一个实例。 而更多的我打开/关闭活动B,做大在logcat中报道的内存占用。 通过MAT强制GC不排除到活动B内存的引用。

我有三个问题。

  1. 为什么内存/ GC行为跨越不同设备的不同?

  2. 在S3,将操作系统最终会回来,GC滞留b活动对象(换句话说,我不应该担心,因为Android将在崩溃之前清理)?

  3. 如果没有,你在哪里的主题和AudioManager引用来的,我会怎么清除呢?

由于有经验的“泄漏猎人”在那里!

Answer 1:

UPDATE:为了查看是否“搁浅”存储器由活动乙左事实上是一个问题,我创建活动A和B之间的环:

--- A calls startActivityForResult() on B
--- B calls finish()
--- onActivityResult() in A calls B again, etc...

我让它飞了约15000次迭代,程序没有崩溃。 因此,即使在JVM这款手机和操作系统版本上(三星S3,4.1.1)离开在内存中的B类引用,即使在活动B调用完成(),它似乎有一个后清理了一番,作为到B类引用的数量并没有在测试过程中单调递增。

事实上,我在测试过程中产生的几堆转储,从来没有见过超过约100为B类的实例 - 而不是在15K我希望看到,如果没有其他的清理。 在logcat的GC报表还显示内存使用持续两个向上和向下,尽管大量活性B的调用的

我的结论是,我不应该担心完成后的堆转储B类引用的存在()调用,因为它似乎是,JVM上这款手机/ Android版本不使用某种形式的延期清理。

注意:这是基于我跑测试我的推断,所以如果有人知道不同,请分享。 谢谢!



文章来源: Calling finish() does not clear memory references to Activity