系统UI开发规范&技巧 — 内存篇

每个 Android 应用程序在运行时都会被分配一个独立的进程,每个进程有自己的虚拟地址空间。SystemUI作为高优常驻进程,高效地分配和管理设备的内存资源,是确保SystemUI流畅运行的关键。

内存相关简介

Meminfo

Android meminfo 字段详解https://developer.android.com/topic/performance/memory-overview?hl=zh-cnhttps://developer.android.com/tools/dumpsys?hl=zh-tw

dumpsys meminfo 命令用于获取 Android 设备上进程的内存信息。以下是 dumpsys meminfo 命令输出中每个信息的含义:

adb shell dumpsys meminfo com.android.systemui

Applications Memory Usage (in Kilobytes):
Uptime: 95803295 Realtime: 99507806
 
** MEMINFO in pid 4786 [com.android.systemui] **
                   Pss  Private  Private  SwapPss      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap   110314   110272        0     5629   118392   146568   117524    23973
  Dalvik Heap    49021    48956        0       32    57504   133014    34710    98304
 Dalvik Other    12309     9888        0       28    16180                           
        Stack     4708     4708        0      308     4716                           
       Ashmem     2393     2372        0        0     5328                           
    Other dev      263        4      252        0      908                           
     .so mmap     3904      220      272       68    73000                           
    .jar mmap     2590        0      164        0    59396                           
    .apk mmap    60625       16    53356       12    82568                           
    .ttf mmap     3654        0      680        0    28028                           
    .dex mmap      786        0      708        4     1996                           
    .oat mmap      319        0        0        0    16868                           
    .art mmap     1313      992      124        0    23432                           
   Other mmap     1653        4       68        0     5148                           
   EGL mtrack     5456     5456        0        0     5456                           
    GL mtrack    34504    34504        0        0    34504                           
      Unknown    33610    31820     1788      908    34964                           
        TOTAL   334411   249212    57412     6989   568388   279582   152234   122277
 
 App Summary
                       Pss(KB)                        Rss(KB)
                        ------                         ------
           Java Heap:    50072                          80936
         Native Heap:   110272                         118392
                Code:    55436                         266716
               Stack:     4708                           4716
            Graphics:    39960                          39960
       Private Other:    46176
              System:    27787
             Unknown:                                   57668
 
           TOTAL PSS:   334411            TOTAL RSS:   568388       TOTAL SWAP PSS:     6989
 
 Objects
               Views:     2433         ViewRootImpl:       12
         AppContexts:       73           Activities:        0
              Assets:       53        AssetManagers:        0
       Local Binders:      969        Proxy Binders:      335
       Parcel memory:      149         Parcel count:      257
    Death Recipients:       36             WebViews:        0
 
 Native Allocations
                         Count                       Total(kB)
                        ------                         ------
    Other (malloced):     8327                            795
 Other (nonmalloced):     1468                            823
   Bitmap (malloced):      206                          18771
Bitmap (nonmalloced):       18                           2998
 
 SQL
         MEMORY_USED:      757
  PAGECACHE_OVERFLOW:      333          MALLOC_SIZE:       53
 
 DATABASES
      pgsz     dbsz   Lookaside(b) cache hits cache misses cache size  Dbname
PER CONNECTION STATS
         4       24             44   103   110     4  /data/user_de/0/com.android.systemui/databases/notification.db
         4        8                    0     0     0    (attached) temp
         4       24             46    37    30     4  /data/user_de/0/com.android.systemui/databases/notification.db (1)
         4       20             41     3    19     4  /data/user_de/0/com.miui.aod/databases/onetrack_cache
         4       24             43     4    20     5  /data/user_de/0/com.miui.aod/databases/universal_ot_monitor_db
         4       20             41    13    28     4  /data/user_de/0/com.android.systemui/databases/onetrack_cache
         4       20             41     3    28     4  /data/user_de/0/com.android.systemui/databases/onetrack_cache
         4      188             32   114    32     5  :memory:
POOL STATS
     cache hits  cache misses    cache size  Dbname
            140           144           284  /data/user_de/0/com.android.systemui/databases/notification.db
              3            20            23  /data/user_de/0/com.miui.aod/databases/onetrack_cache
              4            21            25  /data/user_de/0/com.miui.aod/databases/universal_ot_monitor_db
             13            29            42  /data/user_de/0/com.android.systemui/databases/onetrack_cache
              3            29            32  /data/user_de/0/com.android.systemui/databases/onetrack_cache
            114            33           147  :memory:
 

纵轴:

横轴:

App Summary:

Gfxinfo

https://developer.android.com/tools/dumpsys?hl=zh-tw

adb shell dumpsys gfxinfo com.android.systemui

关键信息

//frameworks/base/libs/hwui/renderthread/CacheManager.cpp

CacheManager::dumpMemoryUsage

......
Pipeline=Skia (Vulkan)
Memory policy:
  Max surface area: 3548160
  Max resource usage: 510.94MB (x144)
  Background retention: 50% (altUiHidden = true)
  IsSystemOrPersistent
  GPU Context timeout: 10
Contexts: 12 (stopped = 6)
CPU Caches:
  Glyph Cache: 4.99 MB (1 entry)
  Glyph Count: 334 
Total CPU memory usage:
  5228710 bytes, 4.99 MB (0.00 bytes is purgeable)
 
GPU Caches:
  Other:
    Other: 207.56 KB (1 entry)
  Image:
    Surface: 231.20 KB (2 entries)
  Scratch:
    Surface: 7.35 MB (9 entries)
    GrVkTextureRenderTarget: 83.40 MB (37 entries)
    Buffer Object: 254.12 KB (76 entries)
    GrVkImage: 0.00 bytes (48 entries)
Total GPU memory usage:
  95867448 bytes, 91.43 MB (112.19 KB is purgeable)
  
......
 
GraphicBufferAllocator buffers:
            Handle |         Size |     W (Stride) x H | Layers |   Format |      Usage | Requestor
0xb400007241ed1890 |    61.50 KiB |  320 ( 384) x   41 |      1 |        1 | 0x10000300 | passBlur-24893
0xb400007241ed19f0 |   820.00 KiB | 1280 (1280) x  164 |      1 |        1 | 0x     b00 | VRI[DynamicIslandWindow]#10(BLAST Consumer)10
0xb400007241ed74b0 |  1039.50 KiB |  320 ( 384) x  693 |      1 |        1 | 0x10000300 | passBlur-24893
0xb400007241ed87f0 | 13860.00 KiB | 1280 (1280) x 2772 |      1 |        1 | 0x     b00 | VRI[NotificationShade]#11(BLAST Consumer)11
0xb400007241ed92f0 |  1039.50 KiB |  320 ( 384) x  693 |      1 |        1 | 0x10000300 | passBlur-24893
0xb400007241edccb0 |  1039.50 KiB |  320 ( 384) x  693 |      1 |        1 | 0x10000300 | passBlur-24893
0xb400007241edd7b0 |    61.50 KiB |  320 ( 384) x   41 |      1 |        1 | 0x10000300 | passBlur-24893
0xb400007241ede990 | 13860.00 KiB | 1280 (1280) x 2772 |      1 |        1 | 0x     b00 | VRI[NotificationShade]#11(BLAST Consumer)11
0xb400007241ee0250 |    61.50 KiB |  320 ( 384) x   41 |      1 |        1 | 0x10000300 | passBlur-24893
0xb400007241ee0510 | 13860.00 KiB | 1280 (1280) x 2772 |      1 |        1 | 0x     b00 | VRI[NotificationShade]#11(BLAST Consumer)11
0xb400007241ee1170 | 13860.00 KiB | 1280 (1280) x 2772 |      1 |        1 | 0x     b00 | VRI[NotificationShade]#11(BLAST Consumer)11
0xb400007241ee1430 | 13860.00 KiB | 1280 (1280) x 2772 |      1 |        1 | 0x     b00 | VRI[NotificationShade]#11(BLAST Consumer)11
0xb400007241ee1c70 |   820.00 KiB | 1280 (1280) x  164 |      1 |        1 | 0x     b00 | VRI[DynamicIslandWindow]#10(BLAST Consumer)10
0xb400007241f0a570 |    22.75 KiB |  448 ( 448) x   13 |      1 |        1 | 0x     b00 | VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9
0xb400007241f0b5f0 |   820.00 KiB | 1280 (1280) x  164 |      1 |        1 | 0x     b00 | VRI[DynamicIslandWindow]#10(BLAST Consumer)10
0xb400007241f11370 |   820.00 KiB | 1280 (1280) x  164 |      1 |        1 | 0x     b00 | VRI[DynamicIslandWindow]#10(BLAST Consumer)10
0xb400007241f4a310 |    22.75 KiB |  448 ( 448) x   13 |      1 |        1 | 0x     b00 | VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9
0xb400007241f501f0 |    22.75 KiB |  448 ( 448) x   13 |      1 |        1 | 0x     b00 | VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9
0xb400007241f50770 |    22.75 KiB |  448 ( 448) x   13 |      1 |        1 | 0x     b00 | VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9
0xb400007241f67ab0 |    22.75 KiB |  448 ( 448) x   13 |      1 |        1 | 0x     b00 | VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9
0xb400007241f6b5d0 |   820.00 KiB | 1280 (1280) x  164 |      1 |        1 | 0x     b00 | VRI[DynamicIslandWindow]#10(BLAST Consumer)10
0xb400007241f73450 |   260.00 KiB | 1280 (1280) x   52 |      1 |        1 | 0x     b00 | VRI[NavigationBar0]#0(BLAST Consumer)0
0xb400007241f735b0 |   260.00 KiB | 1280 (1280) x   52 |      1 |        1 | 0x     b00 | VRI[NavigationBar0]#0(BLAST Consumer)0
0xb400007241f73710 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar]#1(BLAST Consumer)1
0xb400007241f73c90 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar]#1(BLAST Consumer)1
0xb400007241f73f50 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar]#1(BLAST Consumer)1
0xb400007241f74a50 |   260.00 KiB | 1280 (1280) x   52 |      1 |        1 | 0x     b00 | VRI[NavigationBar0]#0(BLAST Consumer)0
0xb400007241f75550 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar]#1(BLAST Consumer)1
0xb400007241f756b0 |   260.00 KiB | 1280 (1280) x   52 |      1 |        1 | 0x     b00 | VRI[NavigationBar0]#0(BLAST Consumer)0
0xb400007241f76730 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar]#1(BLAST Consumer)1
0xb400007241f774f0 |   260.00 KiB | 1280 (1280) x   52 |      1 |        1 | 0x     b00 | VRI[NavigationBar0]#0(BLAST Consumer)0
0xb400007241f94c90 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar1]#3(BLAST Consumer)3
0xb400007241f95a50 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar1]#3(BLAST Consumer)3
0xb400007241f95d10 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar1]#3(BLAST Consumer)3
0xb400007241f971b0 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar1]#3(BLAST Consumer)3
0xb400007241f980d0 |   760.00 KiB | 1280 (1280) x  152 |      1 |        1 | 0x     b00 | VRI[StatusBar1]#3(BLAST Consumer)3
Total allocated by GraphicBufferAllocator (estimate): 85716.75 KB
Imported gralloc buffers:
+ name:VRI[DynamicIslandWindow]#10(BLAST Consumer)10, id:4793183516421, size:894.00KiB, w/h:1280x164, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:passBlur-24893, id:4793183516420, size:196.00KiB, w/h:320x41, usage: 0x10000300, req fmt:1, fourcc/mod:875708993/576460752303424337, dataspace: 0x8810000, compressed: true
+ name:passBlur-24893, id:4793183516419, size:196.00KiB, w/h:320x41, usage: 0x10000300, req fmt:1, fourcc/mod:875708993/576460752303424337, dataspace: 0x8810000, compressed: true
+ name:passBlur-24893, id:4793183516416, size:1172.00KiB, w/h:320x693, usage: 0x10000300, req fmt:1, fourcc/mod:875708993/576460752303424337, dataspace: 0x8810000, compressed: true
+ name:VRI[NotificationShade]#11(BLAST Consumer)11, id:4793183516415, size:14138.00KiB, w/h:1280x2772, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[NotificationShade]#11(BLAST Consumer)11, id:4793183516413, size:14138.00KiB, w/h:1280x2772, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[NotificationShade]#11(BLAST Consumer)11, id:4793183516412, size:14138.00KiB, w/h:1280x2772, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[NotificationShade]#11(BLAST Consumer)11, id:4793183516411, size:14138.00KiB, w/h:1280x2772, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[DynamicIslandWindow]#10(BLAST Consumer)10, id:4793183516407, size:894.00KiB, w/h:1280x164, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[DynamicIslandWindow]#10(BLAST Consumer)10, id:4793183516406, size:894.00KiB, w/h:1280x164, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[DynamicIslandWindow]#10(BLAST Consumer)10, id:4793183516410, size:894.00KiB, w/h:1280x164, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9, id:4793183516396, size:29.00KiB, w/h:448x13, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9, id:4793183516394, size:29.00KiB, w/h:448x13, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[NotificationShade]#11(BLAST Consumer)11, id:4793183516414, size:14138.00KiB, w/h:1280x2772, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[DynamicIslandWindow]#10(BLAST Consumer)10, id:4793183516409, size:894.00KiB, w/h:1280x164, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9, id:4793183516393, size:29.00KiB, w/h:448x13, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9, id:4793183516392, size:29.00KiB, w/h:448x13, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:passBlur-24893, id:4793183516408, size:196.00KiB, w/h:320x41, usage: 0x10000300, req fmt:1, fourcc/mod:875708993/576460752303424337, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar]#1(BLAST Consumer)1, id:4793183516184, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar1]#3(BLAST Consumer)3, id:4793183516195, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar]#1(BLAST Consumer)1, id:4793183516183, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar1]#3(BLAST Consumer)3, id:4793183516192, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:passBlur-24893, id:4793183516417, size:1172.00KiB, w/h:320x693, usage: 0x10000300, req fmt:1, fourcc/mod:875708993/576460752303424337, dataspace: 0x8810000, compressed: true
+ name:VRI[NavigationBar0]#0(BLAST Consumer)0, id:4793183516178, size:325.00KiB, w/h:1280x52, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar]#1(BLAST Consumer)1, id:4793183516185, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar1]#3(BLAST Consumer)3, id:4793183516191, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[Miui Bottom Caption of Task=1]#9(BLAST Consumer)9, id:4793183516395, size:29.00KiB, w/h:448x13, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[NavigationBar0]#0(BLAST Consumer)0, id:4793183516176, size:325.00KiB, w/h:1280x52, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar]#1(BLAST Consumer)1, id:4793183516181, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar]#1(BLAST Consumer)1, id:4793183516182, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar1]#3(BLAST Consumer)3, id:4793183516194, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:passBlur-24893, id:4793183516418, size:1172.00KiB, w/h:320x693, usage: 0x10000300, req fmt:1, fourcc/mod:875708993/576460752303424337, dataspace: 0x8810000, compressed: true
+ name:VRI[StatusBar1]#3(BLAST Consumer)3, id:4793183516193, size:813.00KiB, w/h:1280x152, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[NavigationBar0]#0(BLAST Consumer)0, id:4793183516180, size:325.00KiB, w/h:1280x52, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[NavigationBar0]#0(BLAST Consumer)0, id:4793183516179, size:325.00KiB, w/h:1280x52, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
+ name:VRI[NavigationBar0]#0(BLAST Consumer)0, id:4793183516177, size:325.00KiB, w/h:1280x52, usage: 0xb00, req fmt:1, fourcc/mod:875708993/576460752303423602, dataspace: 0x8810000, compressed: true
Total imported by gralloc: 89164.00KiB
 
 
属性名解释
Pipeline渲染管线的实现,使用 Vulkan 作为图形 API
Max surface area最大表面面积
Max resource usage最大资源使用量
Background retention后台保留策略
IsSystemOrPersistent应用是是系统或持久性应用
GPU Context timeoutGPU 上下文超时时间
Glyph Cache字形缓存
Glyph Count字形计数
Total CPU memory usageCPU 内存使用总量 skia侧统计
Image图像缓存
Scratch临时缓存
Surface
GrVkTextureRenderTarget提供了一个可以同时用作纹理和渲染目标的资源
Buffer Object用于存储线性数据,如顶点数据、索引数据、uniform 数据等
GrVkImage用于存储多维数据,如纹理、帧缓冲等
Total GPU memory usageGPU 内存使用总量 skia侧统计
GraphicBufferAllocator buffers业务surface申请的buffer,机型不同,surface对应的buffer具体数量也有差异
Imported gralloc buffers图形缓冲区(gralloc buffers)的详细信息

Hprof

Hprof(Heap Profiling)是堆内存快照,通过Hprof文件,可以量化当前系统内存使用情况,因此可以用于分析处理内存泄漏等场景。 Hprof在Android Studio 中可以直接打开并列出类、类的实例和实例的引用树,以此来跟踪内存的使用情况,找出内存泄漏的地方。 对于layer泄漏问题来说,Hprof文件非常关键!!!

  • adb抓取hprof
adb shell 'am dumpheap `pidof com.android.systemui`'
  • 代码中dump
android.os.Debug.dumpHprofData("/data/anr/system_server_memory_leak_" + System.currentTimeMillis() + ".hprof");

如现在我们在源码中封装的

//miui/frameworks/base/core/java/miui/mqsas/sdk/MiuiHprofCrop.java
 
public static synchronized void dumpHprofData(String fileName, boolean isGzip) throws IOException {
    nOpenProxy(fileName, isGzip);
    Debug.dumpHprofData(fileName);
    nCloseProxy();
}
  • hprof打开方式

bugreport中的hprof文件一般在FS/data/miuilog/stability/resleak/layersleak/hprof目录下面,可以先看system_server的hprof文件。

hprof文件的打开方式有多种,直接将文件拖拽到AS中即可打开,可以解析之后使用MAT打开

  • 使用Android Studio打开

名称描述
Class name类名
Allocations这个类的分配的实例总数
Native Size从 C 或 C++ 代码分配的对象的内存
Shallow Size所选实例的大小,计算对象自身的内存占用情况,不考虑对象引用的其他对象所占用的内存空间
Shallow Size = [类定义] + 父类fields所占空间 + 自身fields所占空间 + [alignment]
Retained Size实例A的Retained Size是指, 当实例A被回收时, 可以同时被回收的实例的Shallow Size之和
比如某个Bitmap实例的Retained Size很小, 证明它内部的byte数组被复用了, 有另一个Bitmap实例指向了同一个byte数组
Instance具体的实例
Reference所选实例的引用,以及指向该引用的引用可以查看引用链
DepthGC根节点到所选实例的最短路径的深度
  • 使用MAT打开

使用platform-tools中的工具转换后在MAT进行内存相关的diff,比较直观可以看出内存大小和对象数量的差异

./hprof-conv hprofData/bg_com.android.systemui-3.hprof bg_standard_3.hprof

Native Heap Insight

堆内存检视方案(Native Heap Insight)Systemui的native泄漏进展计划以及澄清文档

堆内存检视方案,用于分析和报告运行时堆内存使用情况,用于拆分Native heap内存申请情况

  • 使用步骤:

    1. 需要userroot或者userdebug的包;

    2. 通过如下命令,之后便可使用Native Heap Insight:

      adb root
      adb remount
      adb shell setprop persist.track.malloc.enable    track-heap
      adb shell setprop persist.track.malloc.program   com.android.systemui
      adb shell stop 
      adb shell start
    3. 对需要测试的场景进行操作,操作一段时间结束后通过如下命令获取相关日志:

    adb shell 'kill -51 pidof com.android.systemui'
    1. 查看日志,该日志将Native排名前十的堆栈进行打印,通过查看堆栈发现Native异常分配内存的情况;

  • 解题实战:

https://jira-phone.mioffice.cn/browse/BUGOS2-336752

问题场景下泄漏的对象为 SkTypeface

02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap: Total size is 723307822 bytes, and here gives Top-10 stacks: // systemui总共占用723307822
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap: -> stack key "2410eb862714708e" 
: ref.   2262, size 538790304, 18358s, sampled at 2025-02-26 23:05:17 // SkTypeface堆栈调用2262次,大小538790304
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #00 pc 0000000000045618  /apex/com.android.runtime/lib64/bionic/libc.so (malloc+76)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #01 pc 000000000034ae60  /system/lib64/libhwui.so (sk_malloc_flags(unsigned long, unsigned int)+40)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #02 pc 0000000000039364  /system/lib64/libft2.so (ft_mem_qrealloc+164)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #03 pc 000000000008048c  /system/lib64/libft2.so (tt_set_mm_blend+1328)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #04 pc 000000000007ee00  /system/lib64/libft2.so (TT_Set_Var_Design+532)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #05 pc 0000000000043448  /system/lib64/libft2.so (FT_Set_Var_Design_Coordinates+180)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #06 pc 00000000002eecb4  /system/lib64/libhwui.so (SkTypeface_FreeType::getFaceRec() const+380)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #07 pc 00000000002eeabc  /system/lib64/libhwui.so (AutoFTAccess::AutoFTAccess(SkTypeface_FreeType const*)+72)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #08 pc 0000000000535b90  /system/lib64/libhwui.so (SkTypeface_FreeType::onGetTableData(unsigned int, unsigned long, unsigned long, void*) const+64)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #09 pc 000000000029a100  /system/lib64/libhwui.so (SkTypeface_FreeType::onGlyphMaskNeedsCurrentColor() const::$0::operator()() const (._uniq.323675718633992985652658630537108723239)+44)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #10 pc 000000000029a0a8  /system/lib64/libhwui.so (void SkOnce::operator()<SkTypeface_FreeType::onGlyphMaskNeedsCurrentColor() const::$0>(SkTypeface_FreeType::onGlyphMaskNeedsCurrentColor() const::$_0&&) (._uniq.323675718633992985652658630537108723239)+52)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #11 pc 0000000000522ed0  /system/lib64/libhwui.so (SkTypeface_FreeType::onGlyphMaskNeedsCurrentColor() const+40)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #12 pc 000000000028fc38  /system/lib64/libhwui.so (SkStrikeSpec::SkStrikeSpec(SkFont const&, SkPaint const&, SkSurfaceProps const&, SkScalerContextFlags, SkMatrix const&)+268)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #13 pc 0000000000270b78  /system/lib64/libhwui.so (android::PaintGlue::getMetricsInternal(long, SkFontMetrics*, bool) (.__uniq.295321301672566532533700490907482056561)+492)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #14 pc 000000000053e910  /system/lib64/libhwui.so (android::PaintGlue::getFontMetricsInt(JNIEnv*, _jobject*, long, _jobject*, unsigned char) (._uniq.295321301672566532533700490907482056561)+68)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #15 pc 00000000001f6a58  /system/framework/arm64/boot-framework.oat (art_jni_trampoline+104)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #16 pc 00000000005cae9c  /system/framework/arm64/boot-framework.oat (android.text.TextLine.expandMetricsFromPaint+108)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #17 pc 0000000000792304  /apex/com.android.art/lib64/libart.so (nterp_helper+148)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #18 pc 00000000004b13b8  /system/framework/framework.jar (offset 0x11ff000)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #19 pc 00000000007938c4  /apex/com.android.art/lib64/libart.so (nterp_helper+5716)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #20 pc 00000000004b0d30  /system/framework/framework.jar (offset 0x11ff000)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #21 pc 00000000007938c4  /apex/com.android.art/lib64/libart.so (nterp_helper+5716)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #22 pc 00000000004b1c28  /system/framework/framework.jar (offset 0x11ff000)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #23 pc 0000000000cdea10  [anon_shmem:dalvik-jit-code-cache] (offset 0x2000000) (android.text.TextLine.measure+640)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #24 pc 0000000000793f98  /apex/com.android.art/lib64/libart.so (nterp_helper+7464)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #25 pc 00000000004b1cf0  /system/framework/framework.jar (offset 0x11ff000)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #26 pc 00000000007931c0  /apex/com.android.art/lib64/libart.so (nterp_helper+3920)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #27 pc 0000000000499510  /system/framework/framework.jar (offset 0x11ff000)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #28 pc 000000000081a924  /system/framework/arm64/boot-framework.oat (android.widget.TextView.onMeasure+532)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #29 pc 000000000075309c  /system/framework/arm64/boot-framework.oat (android.view.View.measure+1916)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #30 pc 00000000007e3b0c  /system/framework/arm64/boot-framework.oat (android.view.ViewGroup.measureChildWithMargins+252)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #31 pc 0000000000843f78  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.measureChildBeforeLayout+56)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #32 pc 0000000000844548  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.measureHorizontal+1448)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #33 pc 0000000000846d08  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.onMeasure+72)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #34 pc 000000000075309c  /system/framework/arm64/boot-framework.oat (android.view.View.measure+1916)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #35 pc 00000000007e3b0c  /system/framework/arm64/boot-framework.oat (android.view.ViewGroup.measureChildWithMargins+252)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #36 pc 000000000083eb9c  /system/framework/arm64/boot-framework.oat (android.widget.FrameLayout.onMeasure+348)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #37 pc 00000000003976dc  [anon_shmem:dalvik-jit-code-cache] (offset 0x2000000) (com.android.systemui.statusbar.views.LimitedSizeFrameLayout.onMeasure+76)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #38 pc 000000000075309c  /system/framework/arm64/boot-framework.oat (android.view.View.measure+1916)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #39 pc 00000000007e3b0c  /system/framework/arm64/boot-framework.oat (android.view.ViewGroup.measureChildWithMargins+252)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #40 pc 000000000083eb9c  /system/framework/arm64/boot-framework.oat (android.widget.FrameLayout.onMeasure+348)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #41 pc 000000000075309c  /system/framework/arm64/boot-framework.oat (android.view.View.measure+1916)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #42 pc 00000000007e3b0c  /system/framework/arm64/boot-framework.oat (android.view.ViewGroup.measureChildWithMargins+252)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #43 pc 0000000000843f78  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.measureChildBeforeLayout+56)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #44 pc 0000000000844548  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.measureHorizontal+1448)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #45 pc 0000000000846d08  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.onMeasure+72)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #46 pc 000000000075309c  /system/framework/arm64/boot-framework.oat (android.view.View.measure+1916)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #47 pc 00000000007e3b0c  /system/framework/arm64/boot-framework.oat (android.view.ViewGroup.measureChildWithMargins+252)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #48 pc 0000000000843f78  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.measureChildBeforeLayout+56)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #49 pc 0000000000845ee4  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.measureVertical+884)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #50 pc 0000000000846cec  /system/framework/arm64/boot-framework.oat (android.widget.LinearLayout.onMeasure+44)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #51 pc 000000000075309c  /system/framework/arm64/boot-framework.oat (android.view.View.measure+1916)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #52 pc 00000000007e3b0c  /system/framework/arm64/boot-framework.oat (android.view.ViewGroup.measureChildWithMargins+252)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #53 pc 000000000083eb9c  /system/framework/arm64/boot-framework.oat (android.widget.FrameLayout.onMeasure+348)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #54 pc 000000000075309c  /system/framework/arm64/boot-framework.oat (android.view.View.measure+1916)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #55 pc 0000000000d4eee4  [anon_shmem:dalvik-jit-code-cache] (offset 0x2000000) (androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure+2276)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #56 pc 000000000015574c  [anon_shmem:dalvik-jit-code-cache] (offset 0x2000000) (androidx.constraintlayout.core.widgets.analyzer.DependencyGraph.measure+108)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #57 pc 0000000000cfb8ac  [anon_shmem:dalvik-jit-code-cache] (offset 0x2000000) (androidx.constraintlayout.core.widgets.analyzer.DependencyGraph.basicMeasureWidgets+3612)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #58 pc 0000000000959aa8  [anon_shmem:dalvik-jit-code-cache] (offset 0x2000000) (androidx.constraintlayout.widget.ConstraintLayout.resolveSystem+3048)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #59 pc 0000000000c3cdb4  [anon_shmem:dalvik-jit-code-cache] (offset 0x2000000) (androidx.constraintlayout.widget.ConstraintLayout.onMeasure+3700)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #60 pc 0000000000396984  [anon_shmem:dalvik-jit-code-cache] (offset 0x2000000) (com.android.systemui.shade.MiuiNQSContainer.onMeasure+36)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #61 pc 000000000075309c  /system/framework/arm64/boot-framework.oat (android.view.View.measure+1916)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #62 pc 00000000007e3b0c  /system/framework/arm64/boot-framework.oat (android.view.ViewGroup.measureChildWithMargins+252)
02-26 23:05:21.593  1000  3335  3409 I INJECT track-heap:     #63 pc 000000000083eb9c  /system/framework/arm64/boot-framework.oat (android.widget.FrameLayout.onMeasure+348)
  • SkTypeface是Skia库中的一个类,用于处理字体相关的功能。
  • TextView.onMeasure() 时,需要使用 skia中的 SkTypeface 进行文字测量,skia中使用StrikeCache进行SkTypeface的复用管理,一般情况下 SkTypeface 的数量不会太大。
  • 问题场景下 SkTypeface 未复用,生成了大量新的 SkTypeface 对象,原因是业务侧一直在新建TextView,并且设置了 FontVariationSettings属性 (例如 ‘wght’)。

解决方案:

找到使用remoteview的业务并在需要频繁对TextView.onMeasure()场景取消fontVariationSettings的设置

Heap_Profile

https://perfetto.dev/docs/getting-started/memory-profiling

谷歌提供dump 内存申请堆栈信息的工具,对于dump native信息非常实用

使用下面命令开始抓取trace文件

heap_profile -c 间隔时间 -n 包名

例如每100ms抓取一次systemui的内存: ./heap_profile -c 100 -n com.android.systemui

通过申请native内存的堆栈排查native内存堆积的原因

  • 解题实战:

https://jira-phone.mioffice.cn/browse/BUGOS2-618194

bitmap堆积,所有的hprof抓取的bitmap已经释放,看raw-trace,通过getIconDescriptor方法创建的bitmap就有2G

解决方案:

copy一个不可变的bitmap

Smaps

抓取方式:

拿到systemui的进程号,后续需要用到,每个手机不一样

adb shell ps -A | grep com.android.systemui

adb shell cat /proc/pid/smaps > systemui_smaps.txt

通过 https://github.com/Gracker/Android-App-Memory-Analysis 提供的脚本拆分 smaps文件:

python3 smaps_parser.py -f smaps >smaps_parser.txt

python3 smaps_parser.py -f ./data/smaps3 > ./data/smaps_parser3.txt

可以得到比meminfo更详细的内存信息:

  • 解题实战:

systemui开机内存超标

https://jira-phone.mioffice.cn/browse/BUGOS2-594816

开机后没有使用ScreenRecorder,但是在systemui的内存中却mmap了ScreenRecorder的apk

解决方案:

  • 判断完是否支持展示后就destroy掉,且不将tile添加在集合中,后续只有被添加在控制中心里后才去创建tile

Mem_profile

Franklin1 Android Memtrack

mem_profile是用于mail 平台获取GPU相关内存信息,所以cat这个信息主要用于分析Mtk/Xring平台的GL mtrack内存信息,如果需要更进阶的分析graphics的方法,可以参考这篇文档Graphics内存数据拆解

Mtk平台直接执行如下命令

cat /sys/kernel/debug/mali0/ctx/$(pidof com.android.systemui)_*/mem_profile

adb shell 'cat /sys/kernel/debug/mali0/ctx/$(pidof com.android.systemui)_*/mem_profile'

Xring平台,需要

如果出现/sys/kernel/debug下无内容得情况,则需要先执行:adb shell mount -t debugfs none /sys/kernel/debug

cat mem_profile之前需要先执行如下命令:

adb shell setprop vendor.mali.xfeature_mem_usage_report 1

adb shell stop

adb shell start

通过mem_profile可以获取GFX Device Memory CPU Uncached、Vulkan Bound Buffer Memory、Vulkan Bound Image Memory通道相关的GPU内存信息,这些内存主要通过vkAllocateMemory api申请。

OS3 全局岛内存优化实战

OS3全局岛内存优化

AI+mem

Systemui内存专用内存分析能力

systemui开机内存基线

SystemUI开机内存基线

参考文档

Franklin1 Android Memtrack

OS3全局岛内存优化

Android meminfo 字段详解

堆内存检视方案(Native Heap Insight)

Systemui的native泄漏进展计划以及澄清文档