Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
zhengzhong1 opened this issue May 17, 2024 · 7 comments
Open

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

zhengzhong1 opened this issue May 17, 2024 · 7 comments

Comments

@zhengzhong1
Copy link

zhengzhong1 commented May 17, 2024

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

@zhengzhong1 zhengzhong1 changed the title 泄露分析报告内容 泄露分析报告内容不完整 May 17, 2024
@zefengsysu
Copy link
Contributor

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

@zhengzhong1
Copy link
Author

zhengzhong1 commented May 21, 2024

由于实际泄露相关信息不方便提供,以下是使用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
Copy link
Author

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

@zhengzhong1
Copy link
Author

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

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

@zhengzhong1
Copy link
Author

@zefengsysu 辛苦帮忙看看

@zhengzhong1
Copy link
Author

更新分析结论:
造成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
Copy link

Xinmeng322 commented Jun 14, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants