Android显存profile方法、mali芯片显存占用高的问题

获取显存值

安卓上debug显存,除了游戏引擎自带的profiler外,还有更底层的统计方式,用adb获取内存大小,命令为:

xml 复制代码
adb shell dumpsys meminfo <应用包名>

这可以获取到类似下列的列表:

yaml 复制代码
Applications Memory Usage (in Kilobytes):
Uptime: 1307163772 Realtime: 1442234389

** MEMINFO in pid 26060 [games.guanyou.ca.ymr] **
                   Pss  Private  Private  SwapPss      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap    30104    30024       12      105    30888    48356    45145     3212
  Dalvik Heap     1815     1676       36       74     2616    11550     2887     8663
 Dalvik Other     1668     1556       56        0     2172
        Stack     1892     1892        0        0     1900
       Ashmem      136        0        0        0     1020
      Gfx dev      392      392        0        0      396
    Other dev       19        4        8        0      544
     .so mmap    77560    11596    61188        8   111328
    .jar mmap     4411        0     2012        0    44044
    .apk mmap      441        0       12        0     1812
    .ttf mmap     2213        0      384        0     5584
    .dex mmap     7177       52     7072        0     7936
    .oat mmap       31        0        0        0     2004
    .art mmap     7700     5656     1060       43    16472
   Other mmap    10389        8    10220        0    11420
   EGL mtrack    37000    37000        0        0    37000
    GL mtrack      764      764        0        0      764
      Unknown    16209    16068       92        1    16596
        TOTAL   200152   106688    82152      231   294496    59906    48032    11875

 App Summary
                       Pss(KB)                        Rss(KB)
                        ------                         ------
           Java Heap:     8392                          19088
         Native Heap:    30024                          30888
                Code:    82316                         172756
               Stack:     1892                           1900
            Graphics:    38156                          38160
       Private Other:    28060
              System:    11312
             Unknown:                                   31704

           TOTAL PSS:   200152            TOTAL RSS:   294496       TOTAL SWAP PSS:      231

和图形相关的有如下信息:

makefile 复制代码
Gfx dev      392      392        0        0      396
EGL mtrack    37000    37000        0        0    37000
GL mtrack      764      764        0        0      764

Graphics:    38156                          38160

上述是在adreno芯片的手机上获取到的信息,而如果是在mali gpu的手机获取,只会获取到如下信息:

makefile 复制代码
GL mtrack   111392   111392        0        0   111392\

Graphics:   111392                         111392

观察上述信息,我们能简单得到一些结论: adreno芯片获取的信息中,Gfx dev + EGL mtrack + GL mtrack的结果,恰好是Graphics中的值。

多次在手机运行demo程序中,我发现多次用adb获取上述信息时,adreno手机上,Gfx dev时刻在小范围波动,每次获取都不同;EGL mtrack不会轻易发生变化,GL mtrack和纹理相关,在demo程序中添加纹理,大小会反应在GL mtrack中,且纹理的大小几乎就是GL mtrack的增量(有极小的差异,可能和其他渲染用资源有关)。

复制一个特效,再将其删除,理论上只有shader不会被卸载,其他资源都应该被卸载,反应在上述结果中,GL mtrack再复制前和删除后几乎没有变化,而Gfx dev有很大变化,说明Gfx dev内包含Shader Program的内存。

mali芯片只有GL mtrack并和Graphics值相等,怀疑mali芯片获取的GL mtrack中,包含了Gfx dev + EGL mtrack,不过与时刻变化的adreno芯片Gfx dev不同,mali芯片GL mtrack不会时刻变化,而是当demo重新启动时,每次重启app,这里值都有微小差异。

发现的问题与调查问题

在mali芯片的gpu中,我们播放的一个粒子特效后,内存值显著高于adreno芯片。

在Android Studio的Profiler界面(View->Tool Windows->Profiler)可以查看内存,其中包含Other、Code、Stack、Graphics、Native、Java等项:

用左侧Record native allocation可以记录堆栈申请的内存,并根据开始与结束时内存的释放,查看是否有未释放的内存,例如我record灰色部分:

将检查部分改成Arrange by callstack展开内容,用remaining size排序,首先是看起来是有0.5MB的纹理创建导致的内存未清理,后面还有glBindFramebuffer等申请的内存未释放,这些内存是在libGLES.mali.so,也就是芯片厂商提供的动态库内部申请的。

合理怀疑可不可能是Unity有些申请的纹理为释放,因此用高通设备走同样的流程对比,发现高通的remaining size也就不到400KB,并且也没有纹理相关的堆栈,说明这与Unity无关,是芯片厂dll内部申请的内存未释放。

将同一特效反复加载播放然后删除,mali和adreno设备的曲线有明显区别:

因此几乎可以判定,mali芯片的gles动态库底层有一个池子。

👀关注公众号:Android老皮!!!欢迎大家来找我探讨交流👀

相关推荐
louisgeek14 分钟前
Android NSD 网络服务发现
android
张可1 小时前
历时两年半开发,Fread 项目现在决定开源,基于 Kotlin Multiplatform 和 Compose Multiplatform 实现
android·前端·kotlin
余辉zmh1 小时前
【Linux系统篇】:信号的生命周期---从触发到保存与捕捉的底层逻辑
android·java·linux
孤鸿玉2 小时前
[Flutter小试牛刀] 低配版signals,添加多层监听链
android·前端·响应式设计
雨和卡布奇诺2 小时前
LiveData源码浅析
android
淡蓝色_justin2 小时前
Hilt-plus 简介
android·android jetpack
app1e2342 小时前
ctfshow web入门 命令执行(29-77)
android·前端
恋猫de小郭5 小时前
Flutter 在 Dart 3.8 开始支持 Null-Aware Elements 语法,自动识别集合里的空元素
android·前端·flutter
fatiaozhang95275 小时前
咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包
android·电视盒子·av1·机顶盒rom·魔百盒刷机