LeakCanary是Square公司推出个一个内存泄露检测工具,
[地址:[https://square.github.io/leak...]()](https://square.github.io/leak...
应用
简略应用,
在我的项目Model的build.gradle文件中dependencies{}中退出
debugImplementation 'com.squareup.leakcanary:leakcanary-android:version'
而后在你的App中的onCreate()办法中增加
LeakCanary.install(this);
这样LeakCanary就能够监控零碎的Activity的内存泄露了,默认应用只能检测到Activity的内存泄露。
如果你想检测其余对象的内存泄露,能够自定义监控对象。
refWatcher = LeakCanary.install(this);
LeakCanary.install(this)
办法返回一个RefWatcher
对象,调用该队的的watch()办法就行了。
该办法的签名如下
//传入你想检测的对象public void watch(Object watchedReference) { watch(watchedReference, "");}
原理
LeakCanary 中对内存透露检测的外围原理就是基于 WeakReference 和 ReferenceQueue 实现的。
1. 当一个 Activity 须要被回收时,就将其包装到一个 WeakReference 中,并且在 WeakReference 的结构器中传入自定义的 ReferenceQueue。2. 而后给包装后的 WeakReference 做一个标记 Key,并且在一个强援用 Set 中增加相应的 Key 记录3. 最初被动触发 GC,遍历自定义 ReferenceQueue 中所有的记录,并依据获取的 Reference 对象将 Set 中的记录也删除
通过下面 3 步之后,还保留在 Set 中的就是:该当被 GC 回收,然而理论还保留在内存中的对象,也就是产生透露了的对象
public static RefWatcher install(Application application) { return install(application, DisplayLeakService.class);} public static RefWatcher install(Application application, Class<? extends AbstractAnalysisResultService> listenerServiceClass) { if (isInAnalyzerProcess(application)) { return RefWatcher.DISABLED; } enableDisplayLeakActivity(application); HeapDump.Listener heapDumpListener = new ServiceHeapDumpListener(application, listenerServiceClass); RefWatcher refWatcher = androidWatcher(application, heapDumpListener); // LeakCanary 中监听 Activity 生命周期是由 ActivityRefWatch 来负责的,次要是通过注册 Android 零碎提供的 ActivityLifecycleCallbacks,来监听 Activity 的生命周期办法的调用, ActivityRefWatcher.installOnIcsPlus(application, refWatcher);//默认只检测Activity的内存泄露 return refWatcher;//返回refWatcher对象, }
RefWatcher对象的构造方法如下。
private final Executor watchExecutor; //线程池 private final DebuggerControl debuggerControl; private final GcTrigger gcTrigger;//GC触发器 private final HeapDumper heapDumper; private final Set<String> retainedKeys; //检测对象的Key汇合 private final ReferenceQueue<Object> queue;//若援用队列 private final HeapDump.Listener heapdumpListener; public RefWatcher(Executor watchExecutor, DebuggerControl debuggerControl, GcTrigger gcTrigger,HeapDumper heapDumper, HeapDump.Listener heapdumpListener) { this.watchExecutor = checkNotNull(watchExecutor, "watchExecutor"); this.debuggerControl = checkNotNull(debuggerControl, "debuggerControl"); this.gcTrigger = checkNotNull(gcTrigger, "gcTrigger"); this.heapDumper = checkNotNull(heapDumper, "heapDumper"); this.heapdumpListener = checkNotNull(heapdumpListener, "heapdumpListener"); retainedKeys = new CopyOnWriteArraySet<>(); queue = new ReferenceQueue<>(); }咱们看下ActivityRefWatcher这个类的外部实现,该类只反对ICE_CREAM_SANDWICH以上的版本。@TargetApi(ICE_CREAM_SANDWICH) public final class ActivityRefWatcher { private final Application application; private final RefWatcher refWatcher; public static void installOnIcsPlus(Application application, RefWatcher refWatcher) { 低于ICE_CREAM_SANDWICH版本的本人在BaseActivity的onDestroy办法中解决 if (SDK_INT < ICE_CREAM_SANDWICH) { // If you need to support Android < ICS, override onDestroy() in your base activity. return; } ActivityRefWatcher activityRefWatcher = new ActivityRefWatcher(application, refWatcher); activityRefWatcher.watchActivities(); } /** * Constructs an {@link ActivityRefWatcher} that will make sure the activities are not leaking * after they have been destroyed. */ public ActivityRefWatcher(Application application, final RefWatcher refWatcher) { this.application = checkNotNull(application, "application"); this.refWatcher = checkNotNull(refWatcher, "refWatcher"); } public void watchActivities() { // Make sure you don't get installed twice. stopWatchingActivities();// application注册ActivityLifecycleCallbacks接口 application.registerActivityLifecycleCallbacks(lifecycleCallbacks); } public void stopWatchingActivities() { application.unregisterActivityLifecycleCallbacks(lifecycleCallbacks); } private final Application.ActivityLifecycleCallbacks接口 lifecycleCallbacks = new Application.ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } //在Activity销毁时开启检测 @Override public void onActivityDestroyed(Activity activity) { ActivityRefWatcher.this.onActivityDestroyed(activity); } }; //检测 void onActivityDestroyed(Activity activity) { refWatcher.watch(activity); }}
最初调用refWatcher对象的watch办法。最初回调它的重载办法。
public void watch(Object watchedReference) { watch(watchedReference, "");} public void watch(Object watchedReference, String referenceName) { //对检测对象和援用名称判空 checkNotNull(watchedReference, "watchedReference"); checkNotNull(referenceName, "referenceName"); if (debuggerControl.isDebuggerAttached()) { return; } //检测开始工夫 final long watchStartNanoTime = System.nanoTime(); //随机生成Key String key = UUID.randomUUID().toString(); //将Key放入retainedKeys汇合中,retainedKeys是一个CopyOnWriteArraySet对象。 retainedKeys.add(key); //将检测对象,key,referenceName,queue 构建一个KeyedWeakReference对象 final KeyedWeakReference reference = new KeyedWeakReference(watchedReference, key, referenceName, queue); //向线程池watchExecutor提交一个工作。在该工作里启动检测。 watchExecutor.execute(new Runnable() { @Override public void run() { ensureGone(reference, watchStartNanoTime); } }); } void ensureGone(KeyedWeakReference reference, long watchStartNanoTime) { long gcStartNanoTime = System.nanoTime(); long watchDurationMs = NANOSECONDS.toMillis(gcStartNanoTime - watchStartNanoTime); //移出援用队列里的对象 removeWeaklyReachableReferences(); if (gone(reference) || debuggerControl.isDebuggerAttached()) { return; } //启动垃圾回收 gcTrigger.runGc(); //移出援用队列里的对象 removeWeaklyReachableReferences(); //如果retainedKeys里边仍然蕴含改若援用对象的key.阐明该弱对象援用的对象泄露了。 if (!gone(reference)) { long startDumpHeap = System.nanoTime(); long gcDurationMs = NANOSECONDS.toMillis(startDumpHeap - gcStartNanoTime); //生成Dump文件 File heapDumpFile = heapDumper.dumpHeap(); if (heapDumpFile == null) { // Could not dump the heap, abort. return; } long heapDumpDurationMs = NANOSECONDS.toMillis(System.nanoTime() - startDumpHeap); heapdumpListener.analyze( new HeapDump(heapDumpFile, reference.key, reference.name, watchDurationMs, gcDurationMs, heapDumpDurationMs)); } } //移出如援用对象 private void removeWeaklyReachableReferences() { // WeakReferences are enqueued as soon as the object to which they point to becomes weakly // reachable. This is before finalization or garbage collection has actually happened. //垃圾回收启动之前,一旦弱援用对象援用的对象变得弱援用时,弱援用对象就会退出到它外部的队列里。 KeyedWeakReference ref; //遍历队列,如果队列里的元素等于以后的对象,阐明以后对象被回收了,就从retainedKeys里移出弱援用对象对一个的key. while ((ref = (KeyedWeakReference) queue.poll()) != null) { retainedKeys.remove(ref.key); } } //判断以后的reference对象对象的Key是否蕴含在retainedKeys,如果在就阐明reference没有被垃圾回收 private boolean gone(KeyedWeakReference reference) { return !retainedKeys.contains(reference.key); }