应用内存拆解分析方法

来源飞书 wiki(obj_token: YGCSdw8REo3HyQxdCA4chraPnXe)

附件已本地化attachments/YGCSdw8REo3HyQxdCA4chraPnXe/aggregate_showmap_gfxinfo.py(应用内存分类脚本)、gpu_mem.sh(跨芯片平台图形内存脚本)

应用内存拆解分类

应用内存拆解分类图表1

应用内存拆解分类图表2

📷 内嵌电子表格:sheet token QrP4swQuvhxOLBtKEGLcdHqLnZb(sheet_id ZoRSvc),建议在飞书中查看完整数据。

👉 应用内存分类脚本解析:python aggregate_showmap_gfxinfo.py -s showmap.txt -g gfxinfo.txt(脚本见 aggregate_showmap_gfxinfo.py

应用内存分类脚本运行截图

👉 跨芯片平台获取图形内存脚本(需root权限):adb shell sh /data/local/tmp/gpu_mem.sh <pkgname>(脚本见 gpu_mem.sh

gpu_mem.sh 脚本内容

分析方法

整机内存占用分解成:1)系统静态预留内存;2)内核占用内存;3)进程Pss内存;

排序Top差距项(按Pss)

**Pss内存:**应用进程按比例分摊的物理内存大小,它体现了应用在整机内存占用中的贡献。

SystemUI差距(p1-magic8pro)饼状图:DEX占比39%,nativeHeap占比18%,dalvikNormal占比11%,APK占比8%,APP_VDEX占比6%,dalvik-LinearAlloc占比5%,SO占比4%,GL占比4%

差距项横向对比(按Rss)

**Rss内存:**应用进程实际访问到的物理内存大小,它体现了应用真实访问的数据量。

SystemUI Rss(P1 vs Magic8pro)柱状图:P1设备的nativeHeap、APK、dvmLinearAlloc等内存占用项数值较大

👉 相同项的Pss差距与Rss差距对比,若Pss差距>Rss差距,说明与其他进程shared内存更少,private内存占用更多,反之,情况相反

SystemUI同项对比(Pss差距 vs Rss差距)柱状图:DEX的Pss差距为80000,Rss差距为70000;nativeHeap的Pss差距为30000,Rss差距为35000

Top差距项展开分析

Code(OAT、APK、VDEX、SO)

小米P1(SystemUI OAT)

小米P1(SystemUI OAT)进程内存拆解分析结果表格,列出了VSS、RSS、PSS等指标

荣耀Magic8pro(SystemUI OAT)

荣耀Magic8pro(SystemUI OAT)系统进程内存信息表格

**Vss内存:**进程映射的虚拟内存大小,它体现了所映射文件的大小。

👉 文件大小对比:systemui业务代码文件大小(Vss),P1(164824)是Magic8pro(29668)的5.6倍,造成如此大差距的原因:P1上采用speed全编译模式,将所有java字节码编译成本地机器码;而Magic8pro采用speed-profile编译模式,将部分java热点类及方法编译成本地机器码。使用adb shell pm art dump [packageName]确认应用编译模式。

MIUI AOD和MIUISystemUIPlugin两个应用的内存分析信息:MIUI AOD的arm64编译模式为speed,MIUISystemUIPlugin的arm64编译模式为speed

👉 **文件访问量(Rss)对比:P1(100326)是Magic8pro(23868)的4.2倍,**造成如此大差距的原因:一是dex文件编译模式不同;二是systemui应用引入了dagger框架,它解决组件依赖复杂、降低耦合、提升可维可测性,但它会遍历依赖树,加载解析几乎所有代码。具体分析方法参考:文件页内存调试分析 @王辉

应用内存拆解分析Code(OAT、APK、VDEX、SO)的Top差距项柱状图,紫色为com.android.systemui.dagger包下的类,黄色为com.android.systemui包下的类

👉 优化思路: 1)应用dex文件采用speed-profile编译模式,覆盖应用高频典型场景的热点类和方法,文件大小减少79%(88360K 18712K); 2)aod和plugin插件包,apk插件方式改成jar包等插件方式,跟随systemui主包一起speed-profile编译; 3)仅定制组件不引入dagger功能,以及dagger非核心组件采用懒加载方式,减少代码访问量。

应用内存数据表格,第三行VSS、RSS、PSS值均为18712,文件路径为system_ext@priv-app@MiuiSystemUI@MiuiSystemUI.apk@classes.dex

NativeHeap

JavaHeap(DalvikNormal)

Graphics(GL、EGL)

优化思路

1)修改应用申请内存方式,静态改动态,动态改懒加载;

2)应用dex2oat避免采用speed全编译模式,采用speed-profile模式编译热点类和函数,增强代码和数据的局部性;

3)应用接入OnTrimMemory,在系统内存紧张时,业务主动释放可重建的冷数据;

4)对应用仅使用一次或很少使用的apk,在使用完成后主动dontNeed告知内核回收;

5)应用业务在后台集中工作,避免随机运行,减少内存频繁换入换出量;

6)应用使用系统公共库,避免独自集成系统SDK已有能力,减少引入不必要的私有数据;

7)业务使用外部模块能力时,减少不必要的库依赖,确实需要时,使用动态链接方式,避免静态链接;

8)核心业务与辅助业务采用进程分离方式,根据产品内存规格配置进程常驻与否,根据系统内存压力,查杀辅助业务进程;

👉 内存降负载原则:在用户体验无明显下降的前提下,减少内存占用。