美文网首页
Android gpu memory leak 分析

Android gpu memory leak 分析

作者: 小老鼠oo | 来源:发表于2019-11-24 10:56 被阅读0次

    解bug的时候多,写代码的时候少。(后面可以按照CodeSheep所说,在github找开源项目跟着写写)
    解bug遇到的最多的算是:CPU kernel panic, GPU hang ,Memory leak

    memory leak来源:

    找这个问题不看虚拟地址,看的是物理地址,比如PSS,顺便带了平均分的共享库大小。
    哪些命令可以看PSS?

    • ps
    • procrank
    • dumpsys meminfo

    这些命令可以连接串口看,或者连接adb看。
    我习惯性的用procrank居多,除了看占用PSS最多的AP,在结尾还可以看到总RAM统计,其中cached也算是free ram的。
    (为什么不适用dumpsys meminfo?他与procrank有什么区别?)

    有时会跑stress,看RAM变化,来找哪个AP在leak,或者只是看眼前的1分钟内的变化,可以用一句shell:

    while : ; do free ; procrank ; sleep 1 ; done ;
    

    看总RAM里Free arm的变化,如果发现了确实有leak,需要分析leak来自哪里,一共有3个地方:

    • java heap
    • native heap
    • gpu heap

    如果看到了某个AP有leak,就可以通过dumpsys meminfo <pid> 看它的java heap与native heap,
    native heap可以来自AP的cpp层,也可能是链接的动态库出了问题,而不是AP本身的代码有问题。我主要关注的就是OGLES_v2.so,这里的代码庞大臃肿,且注释稀少,一般没人敢动,只是打patch,基于混乱的理解,让他愈发臃肿。

    native heap memleak:

    OGLES_v2.so里会有很多malloc的地方,最大的malloc不在结构体,而在对临时buffer的system memory malloc,这种很容易看,因为它太大了,一个buffer可能有1M-8M。
    如果是很小的leak,就是哪里的malloc没有free,

    这里有一个方法来查看一个AP内native heap的使用情况:

    • am dumpheap -n <pid> name.log

    要使用这个命令,需要在build.prop设置一些东西,网上和android源码里面的help,都是在Android 5.0上生效的,但android 7.0有变化。当时看过android 7.0这部分源码,才看到怎么去配置:

    //在/system/build.prop
    libc.debug.malloc.program = app_process  //这个不写也能dump出来
    libc.debug.malloc.options = backtrace
    

    然后运行命令am dumpheap,得到name.log,复制到有android源码的host机,原因是需要out/下带symbol的so库,以便于定位malloc最多的动态库中代码行数。

    有一个解析name.log的python脚本,来自github,叫做native_heapdump_viewer.py。
    先指定带symbol的动态库所在位置,然后解析log为html:

    //注意这个路径一定是到/symbol/的,否则不生效
    export ANDROID_PRODUCT_OUT=/<android>/out/target/product/zx2100_148a//symbols/
    
    native_heapdump_viewer.py --symbols /some/path/to/symbols/ heap.log > heap_info.html
    

    这样查看html就可以知道,一个AP的总native heap,和每个函数的malloc占比。从而定位问题。

    GPU driver heap memleak:

    java heap我们平时不会管,在我们看来这是AP问题,不负责处理。
    如果看到java heap与native heap都没有变化,而Procrank里total free ram还在减少,那几乎可以定位是我们的GPU driver出现的leak。
    GPU driver会先从RAM里面reserve一块作为自己内部的显存:local memory(video memroy),我也不知道为什么这么叫,microsoft也是这么叫的。
    local memory一般大概有96M,在device tree配置,后面还有会从system memroy动态拿的部分,称为pcie memory。这部分会很大,按照不同的compress snoop配对,分4个segment。最大的segment会有512M,需要多少拿多少。所以这部分有机会leak。
    (snoop是什么?)

    检查方法是cat /proc/driver/gpu_driver_name,
    这里我们的driver会打印所有的segment中的allocation,通过at_type,就可以看出是谁要求分配的allocation。比如是OGLES,或者是Gralloc。

    什么是snoop:

    在get_allocation_segment_id时,可以看到,

    • 如果有compress_format,就分到COMPRESS,一个HwFormatTable负责hwFormat(HSF_XXX)到CompressFmt(CP_XXX)的映射,不支持就是CP_OFF。
    • 若有USAGE_TEMP/DATA_BUFFER,就用snoopable。
      GRALLOC_USAGE_HW_2D就会置USAGE_TEMP_BUFFER

    相关文章

      网友评论

          本文标题:Android gpu memory leak 分析

          本文链接:https://www.haomeiwen.com/subject/quzkwctx.html