前面的两篇文章介绍了LeakCanary的核心架构和RefWatcher的工作原理,其核心内容就是查找泄漏对象的最短引用路径,这些工作都是在HeapAnalyzerService中完成的。
HeapAnalyzer
HeapAnalyzerService通过调用HeapAnalyzer的checkForLeak方法来进一步分析内存,使用HAHA将RefWatcher传递过来hprof文件解析成Snapshot对象,其中调用的方法包括SnapshotFactory的parse和HprofIndexBuilder的fill方法。解析得到的SnapShot对象和我们用MAT分析内存得出的对象结构类似,其源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public AnalysisResult checkForLeak(File heapDumpFile, String referenceKey) { ... ISnapshot snapshot = null; try { snapshot = openSnapshot(heapDumpFile); IObject leakingRef = findLeakingReference(referenceKey, snapshot); // False alarm, weak reference was cleared in between key check and heap dump. if (leakingRef == null) { return noLeak(since(analysisStartNanoTime)); } String className = leakingRef.getClazz().getName(); AnalysisResult result = findLeakTrace(analysisStartNanoTime, snapshot, leakingRef, className, true); if (!result.leakFound) { result = findLeakTrace(analysisStartNanoTime, snapshot, leakingRef, className, false); } return result; } catch (SnapshotException e) { return failure(e, since(analysisStartNanoTime)); } finally { cleanup(heapDumpFile, snapshot); } } |
它构建了一颗对象引用关系树,我们可以在这颗树中查询各个Object的信息,包括Class信息、内存地址、持有的引用以及被持有引用的关系。