/** * Creates a {@link RefWatcher} that works out of the box, and starts watching activity * references (on ICS+). */ public static RefWatcher install(Application application) { return install(application, DisplayLeakService.class, AndroidExcludedRefs.createAppDefaults().build()); }
这个函数内部直接调用了另外一个重载的函数
/** * Creates a { @link RefWatcher} that reports results to the provided service, and starts watching * activity references (on ICS+). */ public static RefWatcher install(Application application, Class listenerServiceClass, ExcludedRefs excludedRefs) { //判断是否在Analyzer进程里 if (isInAnalyzerProcess(application)) { return RefWatcher.DISABLED; } enableDisplayLeakActivity(application); HeapDump.Listener heapDumpListener = new ServiceHeapDumpListener(application, listenerServiceClass); RefWatcher refWatcher = androidWatcher(application, heapDumpListener, excludedRefs); ActivityRefWatcher.installOnIcsPlus(application, refWatcher); return refWatcher; }
public static boolean isInServiceProcess(Context context, Class serviceClass) { PackageManager packageManager = context.getPackageManager(); PackageInfo packageInfo; try { packageInfo = packageManager.getPackageInfo(context.getPackageName(), GET_SERVICES); } catch (Exception e) { Log.e("AndroidUtils", "Could not get package info for " + context.getPackageName(), e); return false; } String mainProcess = packageInfo.applicationInfo.processName; ComponentName component = new ComponentName(context, serviceClass); ServiceInfo serviceInfo; try { serviceInfo = packageManager.getServiceInfo(component, 0); } catch (PackageManager.NameNotFoundException ignored) { // Service is disabled. return false; } if (serviceInfo.processName.equals(mainProcess)) { Log.e("AndroidUtils", "Did not expect service " + serviceClass + " to run in main process " + mainProcess); // Technically we are in the service process, but we're not in the service dedicated process. return false; } //查找当前进程名 int myPid = android.os.Process.myPid(); ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); ActivityManager.RunningAppProcessInfo myProcess = null; for (ActivityManager.RunningAppProcessInfo process : activityManager.getRunningAppProcesses()) { if (process.pid == myPid) { myProcess = process; break; } } if (myProcess == null) { Log.e("AndroidUtils", "Could not find running process for " + myPid); return false; } return myProcess.processName.equals(serviceInfo.processName); }
private final Executor watchExecutor; private final DebuggerControl debuggerControl; private final GcTrigger gcTrigger; private final HeapDumper heapDumper; private final Set retainedKeys; private final ReferenceQueue
watchExecutor: 执行内存泄露检测的executor
debuggerControl :用于查询是否正在调试中,调试中不会执行内存泄露检测
queue : 用于判断弱引用所持有的对象是否已被GC。
gcTrigger: 用于在判断内存泄露之前,再给一次GC的机会
headDumper: 用于在产生内存泄露室执行dump 内存heap
heapdumpListener: 用于分析前面产生的dump文件,找到内存泄露的原因
excludedRefs: 用于排除某些系统bug导致的内存泄露
retainedKeys: 持有那些呆检测以及产生内存泄露的引用的key。
接下来,我们来看看watch函数背后是如何利用这些工具,生成内存泄露分析报告的。
public void watch(Object watchedReference, String referenceName) { checkNotNull(watchedReference, "watchedReference"); checkNotNull(referenceName, "referenceName"); //如果处于debug模式,则直接返回 if (debuggerControl.isDebuggerAttached()) { return; } //记住开始观测的时间 final long watchStartNanoTime = System.nanoTime(); //生成一个随机的key,并加入set中 String key = UUID.randomUUID().toString(); retainedKeys.add(key); //生成一个KeyedWeakReference final KeyedWeakReference reference = new KeyedWeakReference(watchedReference, key, referenceName, queue); //调用watchExecutor,执行内存泄露的检测 watchExecutor.execute(new Runnable() { @Override public void run() { ensureGone(reference, watchStartNanoTime); } }); }
public final class AndroidWatchExecutor implements Executor { //.... private void executeDelayedAfterIdleUnsafe(final Runnable runnable) { // This needs to be called from the main thread. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { backgroundHandler.postDelayed(runnable, DELAY_MILLIS); return false; } }); } }
void ensureGone(KeyedWeakReference reference, long watchStartNanoTime) { long gcStartNanoTime = System.nanoTime(); //计算从调用watch到进行检测的时间段 long watchDurationMs = NANOSECONDS.toMillis(gcStartNanoTime - watchStartNanoTime); //根据queue移除已被GC的对象的弱引用 removeWeaklyReachableReferences(); //如果内存已被回收或者处于debug模式,直接返回 if (gone(reference) || debuggerControl.isDebuggerAttached()) { return; } //如果内存依旧没被释放,则再给一次gc的机会 gcTrigger.runGc(); //再次移除 removeWeaklyReachableReferences(); if (!gone(reference)) { //走到这里,认为内存确实泄露了 long startDumpHeap = System.nanoTime(); long gcDurationMs = NANOSECONDS.toMillis(startDumpHeap - gcStartNanoTime); //dump出heap报告 File heapDumpFile = heapDumper.dumpHeap(); if (heapDumpFile == HeapDumper.NO_DUMP) { // Could not dump the heap, abort. return; } long heapDumpDurationMs = NANOSECONDS.toMillis(System.nanoTime() - startDumpHeap); heapdumpListener.analyze( new HeapDump(heapDumpFile, reference.key, reference.name, excludedRefs, watchDurationMs, gcDurationMs, heapDumpDurationMs)); } } private boolean gone(KeyedWeakReference reference) { return !retainedKeys.contains(reference.key); } 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; while ((ref = (KeyedWeakReference) queue.poll()) != null) { retainedKeys.remove(ref.key); } }