【发布时间】:2013-01-04 21:30:50
【问题描述】:
在我的应用程序的简化版本中,我有两个活动,A 和 B。活动 A 启动 B,在完成一些工作后 B 调用完成()。在大多数设备(运行 4.2 的 Galaxy Nexus、运行 4.0.4 的 Droid 4 和运行 2.3.4 的 Droid 2)上使用内存分析器工具显示没有活动 B 的痕迹,这正是我的预期。
但是在运行 4.1.1 的三星 S3 上,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 内存的引用。
我有三个问题。
为什么不同设备的内存/GC行为不同?
-
在 S3 上,操作系统最终会回来并 GC 搁浅的活动 B 对象(换句话说,我应该不用担心,因为 Android 会在崩溃前清理它)吗?
李> 如果不是,Thread 和 AudioManager 引用来自哪里,我将如何清除它们?
感谢任何有经验的“泄密者”!
【问题讨论】:
-
我建议在弄乱内存使用之前调用GC,这样你就可以确定这不是一种计时问题。
-
@rekire:进行堆转储的行为会减少所有垃圾,因为垃圾无法访问。
-
“为什么不同设备的内存/GC行为不同?” -- 由于操作系统版本的差异,以及设备制造商所做的更改。 “在 S3 上,操作系统最终会回来并 GC 搁浅的活动 B 对象”——我们应该怎么知道? “(换句话说,我应该不用担心它,因为Android会在崩溃前清理它)?” -- 什么崩溃?
-
@CommonsWare 谢谢你的提示。
-
@CommonsWare:您是否认为存在与调用完成()的活动相关的内存是我应该解决的问题?换句话说,如果我要不断地打开和关闭活动 B,从而增加滞留内存,是否有理由认为操作系统最终会清理它,或者应用程序更有可能最终崩溃?
标签: android memory-leaks back-stack android-memory mat