系统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泄漏进展计划以及澄清文档