检测

首先,笔者准备了一段非常常见的内存泄漏实例,代码如下所示。

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.activity_main);
  5. // 模拟内存泄露 //
  6. Handler handler = new Handler();
  7. handler.postDelayed(new Runnable() {
  8. @Override
  9. public void run() {
  10. Log.d("xys", "Leak");
  11. }
  12. }, 10000L);
  13. // 模拟内存泄露 //
  14. }

这段代码就是典型的Handler导致的内存泄漏。原理非常简单,匿名内部类hold住了Activity的引用,导致Activity无法被释放。这样在Activity该销毁的时候,由于delay的handler hold住了Activity,所以导致了内存泄漏。因此为了模拟Activity的消耗,重复旋转手机,让应用在横竖屏之间切换,这样就会不断重建Activity。

当待测试的App集成了LeakCanary,一旦应用发生内存泄漏,LeakCanary就会在界面上弹出提示。同时,在Log中也会输出相关信息,如图6.82所示。

检测 - 图1 图6.82 LeakCanary日志

在Launcher中,LeakCanary还会生成一个图标入口——Leaks,如图6.83所示。

检测 - 图2 图6.83 LeakCanary图标

点击Leaks进入,即可看见对应时间点的Leaks信息,如图6.84所示。

检测 - 图3 图6.84 LeakCanary信息

从图6.84中,我们可以非常迅速地找到内存泄漏的原因和泄漏的方法。这是目前查找内存泄漏最好的工具,不仅方便而且效率非常高。这也印证了那句话——科技提高生产力。