KwaiAppTeam / KOOM

KOOM is an OOM killer on mobile platform by Kwai.
Other
3.15k stars 420 forks source link

泄露分析报告内容不完整 #279

Open zhengzhong1 opened 3 months ago

zhengzhong1 commented 3 months ago

请问一下泄露的分析报告中, classInfos中部分泄露对象在gcPaths中没有找到对应的GC引用链,直接使用hprof在profiler中可以找到对应泄露的引用链。这个是什么原因?什么样的泄露在分析报告中检测不到泄露的gc 引用链?

zefengsysu commented 3 months ago

辛苦提供下具体 case 我们确认下,最好是包括 KOOM 的分析结果,hprof 文件,还有具体没有引用链的部分

zhengzhong1 commented 3 months ago

由于实际泄露相关信息不方便提供,以下是使用demo模拟的泄露尝试复现场景,真实的工程中gcPaths不完成的泄露比较多,目前仅使用demo复现了其中的一种,辛苦分析一下。

Koom版本:2.2.2 报告及hprof: oom.zip case场景:

  1. map缓存 fragment导致的泄露,仅在报告的classInfos部分出现,gcPaths无对应GC引用链;参考报告中com.kwai.koom.demo.javaleak.mycase.LeakMyFragmen泄露。
zhengzhong1 commented 3 months ago

case2:Fragment嵌套场景,子fragment泄露的gcPaths可以检测到,父fragment泄漏检测到gcPaths,参考报告中com.kwai.koom.demo.javaleak.mycase.LeakHostFragment泄露 报告及hprof: memory.zip

zhengzhong1 commented 3 months ago

还有一个问题,就是classInfos中包含的泄露对象,实际通过hprof分析并没有泄露:

比如activity的泄露检测,生成报告的时候是通过mDestroyed=true且有强引用指向他来判断泄露的吗?没有判断是不是gc Roots的强引用吗?通过hprof文件看,mDestroyed是true,但是没有gcRoots对象的引用activity,被误判成泄露了。

zhengzhong1 commented 3 months ago

@zefengsysu 辛苦帮忙看看

zhengzhong1 commented 2 months ago

更新分析结论: 造成classInfos与gcPaths不一一对应的原因:

  1. shark库分析泄露最短gc root时,存在去重逻辑,参考:heapAnalyzer.kt类 deduplicateShortestPaths 、updateTrie方法; gc root -->obj1-->obj2-->obj3-->obj4 obj2:泄露的activity对象 obj4:泄露的fragment对象 去重后:obj4不会出现在gcPaths内,仅保留obj2,原因:obj4的gc引用链上存在泄露的对象obj2,也就是说obj4的泄露是由obj2的泄露导致的,obj4这种间接泄露,可以通过解决obj2的泄露得到解决,所以无需单独处理;

  2. 根据LeakTrace signature聚合:参考:heapAnalyzer.kt类buildLeakTraces 方法 及LeakTrace 类的 signature; gc root -->obj1-->obj2-->obj3-->obj4 gc root -->obj1-->obj2-->obj3-->obj5

LeakTrace的signature计算方式为:使用GC root引用链计算md5,不包含泄露对象,即:gc root -->obj1-->obj2-->obj3 来计算生成signature,这样会导致泄露对象obj4、obj5计算出来的签名一样,被聚合到成一个。解决方式:生成signature文本中追加上leakclassname即obj4/obj5的类名。

Xinmeng322 commented 2 months ago

你的邮件已收到。