【问题标题】:Using MAT to Understand Android Memory Leaks使用 MAT 了解 Android 内存泄漏
【发布时间】:2014-05-03 05:14:30
【问题描述】:

我正在编写我的第一个应用程序并试图了解如何使用 MAT 来查找潜在的内存泄漏。为了简单起见,我编译了在 Android Studio 中启动新项目时提供的默认 Hello World 应用程序,即

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

}

漂亮而简单。现在,在我的平板电脑上启动此应用程序后,我立即使用 DDMS 和 hprof-conv 转换工具进行堆转储 (heap-conv-1.hprof)。然后我将平板电脑旋转 20 次,让活动经历多个生命周期,之后我进行另一个堆转储 (heap-conv-2.hprof)。

我将两个堆转储文件加载到 MAT 中,比较它们并为 .*MainActivity.* 执行正则表达式。结果是:

现在在旋转后有 7 个 MainActivity 实例。由于我没有对这个应用程序做任何事情,我是否认为这纯粹是因为这些实例还没有被 GC 处理?在这种情况下,我是否认为 Android 在方向更改后不会 GC,并且仅在需要更多内存时才进行 GC?

【问题讨论】:

  • 你是对的,你的设备只是没有运行 GC。 DDMS 有一个强制 GC 的按钮,所以我建议你这样做并获得第三个堆转储:当然,这 7 个 MainActivity 实例将减少到 1。
  • 另外,请注意,您无法确定 android 何时会运行 GC。即使您“强制”它,系统也会对最佳时间做出决定。 Here 非常适合使用 Handler 类创建危险泄漏
  • @Plinio.Santos 在通过 DDMS 强制 GC 后做了第三次堆转储,是的,你是对的,MainActivity 的实例减少到 1。很高兴知道,了解发生了什么很重要如果你有任何机会发现内存泄漏,关于 GC。

标签: android memory-leaks


【解决方案1】:

对于您的代码,它不会占用太多内存并且不会导致泄漏。Application 在您将大量 bitmaps 加载到内存或持有大量对象时占用大量内存。并且使用 @ 987654324@ 长寿命对象的上下文..

这是谷歌开发者关于内存泄漏的精彩视频。Memory leaks

看完之后你就知道了。

【讨论】:

  • 优秀的视频。让我对内存泄漏和使用的工具有了更好的理解。但是,它并没有真正解决我的问题,即 GC 是否在方向更改后发生。事实上,视频暗示 GC 确实发生在oreinetation 改变之后,但正如我一直在观察的那样,正如@Plinio.Santos 以上的cmets,情况并非如此。 +1 虽然是优秀的链接。
  • @JamesB 当方向改变时不保证 GC..Android 系统检测到何时需要内存然后它会 GC 对象。不保证它什么时候运行..