一个非常好的查找内存泄漏的工具
Android开发学习之路-LeakCanary使用
http://www.cnblogs.com/Fndroid/p/5951740.htmlLeakCanary是一个内存泄漏检测库,它可以在我们的应用发生内存泄漏的时候发出提醒,提醒包括通知和Log。GitHub
这个库使用起来比较简单:
①添加依赖:
1 dependencies { 2 debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' 3 releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' 4 testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' 5 }
②自定义Application
1 public class MyApplication extends Application { 2 @Override 3 public void onCreate() { 4 super.onCreate(); 5 if (LeakCanary.isInAnalyzerProcess(this)) { 6 return; 7 } 8 LeakCanary.install(this); 9 } 10 }
这样就可以了。
我们这里通过简单的例子看看它的效果,我们都知道,内存泄漏比较容易发生的,就是因为生命周期不匹配导致的。Android中的组件都是有特定生命周期的,而当这些组件中存在着不可释放的变量时,组件的生命周期便会出现异常,导致无法被GC释放。
这里举一个简单的例子:
1 public class SecondActivity extends AppCompatActivity { 2 static Demo sDemo; 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_second); 8 if (sDemo == null) { 9 sDemo = new Demo(); 10 } 11 finish(); 12 } 13 14 class Demo { 15 } 16 17 }
这个Activity中,存在一个静态的Demo实例,并且这个实例在Activity初始化的时候也进行了初始化,接着我们在初始化完毕后finish掉这个Activity。
因为sDemo是一个静态的变量并且不为null,所以GC不会将其清理,而Activity因为持有这个静态变量,生命周期也不能正常执行,这样这个Activity就被泄漏了。
我们在MainActivity中打开这个Activity,启动应用。
模拟器的状态栏会出现一个图标,我们打开可以得到如下界面:
可以看到,和我们分析的一样,SecondActivity的实例被泄漏了。
实际上,LeakCanary除了会在界面中显示泄漏信息之外,Log中也一样会输出泄漏的具体信息:
这样追踪泄漏的地方就不难了。
LeakCanary 中文使用说明
https://www.liaohuqiu.net/cn/posts/leak-canary-read-me/
LeakCanary--直白的展现Android中的内存泄漏
http://blog.csdn.net/watermusicyes/article/details/46333925
LeakCanary:跟OOM说再见
LeakCanary的Github地址
https://github.com/square/leakcanary/wiki/FAQ
demo
一个非常简单的 LeakCanary demo: https://github.com/liaohuqiu/leakcanary-demo
开始使用
在 build.gradle
中加入引用,不同的编译使用不同的引用:
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}
在 Application
中:
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
这样,就万事俱备了! 在 debug build 中,如果检测到某个 activity 有内存泄露,LeakCanary 就是自动地显示一个通知。
为什么需要使用 LeakCanary?
问得好,看这个文章LeakCanary: 让内存泄露无所遁形
如何使用
使用 RefWatcher
监控那些本该被回收的对象。
RefWatcher refWatcher = {...};
// 监控
refWatcher.watch(schrodingerCat);
LeakCanary.install()
会返回一个预定义的 RefWatcher
,同时也会启用一个 ActivityRefWatcher
,用于自动监控调用 Activity.onDestroy()
之后泄露的 activity。
public class ExampleApplication extends Application {
public static RefWatcher getRefWatcher(Context context) {
ExampleApplication application = (ExampleApplication) context.getApplicationContext();
return application.refWatcher;
}
private RefWatcher refWatcher;
@Override public void onCreate() {
super.onCreate();
refWatcher = LeakCanary.install(this);
}
}
使用 RefWatcher
监控 Fragment:
public abstract class BaseFragment extends Fragment {
@Override public void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity());
refWatcher.watch(this);
}
}