背景与目标
目标:Pss 降低 200MB

测试场景:开机内存
机型对比:小米P1 vs 荣耀Magic8pro
内存差距:166M(166459KB)
内存细分:
文件页(GAP = 189MB)
匿名页-Native(GAP = 29MB)
匿名页-Java(存量Java堆GAP值:8MB)
Top Native MemFun. 一览(按竞品diff值降序)
[嵌入电子表格 Ai1ysVXKBhW6ZrtaeQ3cvZSUnOf]
函数级拆解
更多的 ShaderCache
qglinternal::vkCreatePipelineCache (diff = 11.76MB)
android::BlobCache::set (diff = 8.15MB)
android::BlobCache::Blob::Blob (diff = 1.98MB)
差距总计:21.89 MB
原因分析:
这3个是 Shader Cache相关,根本原因是小米SystemUI中使用了布局层级更为复杂的圆角嵌套效果,导致 ClipStack 更深,Shader组合效果(级联)更多,进而产生更多的 ShaderCache。
优化方案:
目前有一版相关的针对性优化方案正在跟进中,预计优化70%80% (**1619MB**) ---责任人 @王月
更多的 Bitmap 创建
android::Bitmap::allocateHeapBitmap
小米

VIVO:

荣耀:

位图数量差距:+67 (VIVO) / +233 (荣耀)
位图内存差距:+10.7 MB (VIVO) / +5.6 MB (荣耀)
Top 10 位图列举:
- 通知 icon大图 1, 492KB (通知线程,*2张)
业务侧入口函数:
com.android.systemui.statusbar.notification.row.NotificationRowContentBinderInjector$Companion.initAppInfo
- 通知 icon大图2,492KB (*2张)
业务侧入口函数:
com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerInjectorImpl#updateMiuiHeader
- 锁屏大图,367KB

业务侧入口函数:
com.miui.keyguard.biometrics.fod.MiuiGxzwQuickOpenView.
- 锁屏大图,277KB

业务侧入口函数:
com.android.keyguard.blueprint.KeyguardPanelViewSection.addViews
- 通知大图,274KB

业务侧入口函数:
com.android.systemui.shade.NotificationDismissViewController.
- 通知图标,219KB(通知线程)
业务侧入口函数:
com.android.systemui.statusbar.notification.row.NotificationRowContentBinderInjectorImpl#handleAppIcon
- 通知大图,219KB
业务侧入口函数:
com.android.systemui.statusbar.notification.row.NotificationContentView#onMeasure
- 通知大图,219KB
业务侧入口函数:
com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer#onMeasure
- 锁屏大图,219KB (*5张)
业务侧入口函数:
com.android.systemui.statusbar.notification.policy.KeyguardNotificationController$1.handleMessage
- 通知大图,219KB (*4张)
业务侧入口函数:
com.android.systemui.statusbar.notification.utils.NotifImageUtil#getCustomAppIcon

- 通知大图,219KB
业务侧入口函数:
com.android.systemui.statusbar.notification.utils.NotifImageUtil#getCustomAppIcon

- 通知小图,161KB (多张)
业务侧入口函数:
com.android.systemui.statusbar.notification.utils.NotifImageUtil#getSmallIcon
优化方案:
- 非立即显示的Bitmap,考虑 lazy load 懒加载方式来创建
- 静态图片、Icon图标类图片,考虑设计上降低分辨率规格
更多的 RenderNode 创建
android::uirenderer::RenderNode::RenderNode (diff = 2.02MB)
差距总计:2.0 MB

原因分析:
由于dagger框架的使用 + Speed模式,引起几乎全量(90+%,根据dex文件数据访问火焰图)的预加载方案,小米SystemUI会比VIVO在开机启动场景下,创建并并缓存更多的View对象,涉及: 小窗、通知、锁屏、状态栏、控制中心等各模块。
更多的 文字绘制
GrDrawOpAtlas::addToAtlas (diff = 0.77 MB)
SkArenaAlloc::ensureSpace (diff = 1.43 MB)
差距总计:2.2 MB
canvas.dawText \ canvas.drawTextRun \ canvas.drawTextOnPath 等文字绘制API 调用触发。
SkArenaAlloc, 是Skia 中的一个 arena / bump-pointer 内存分配器,用于存储 绘制过程中的临时对象

原因分析:
View加载与预加载过程中,小米比VIVO触发了更多次的文字绘制,上层代码表现为更多的TextView渲染。
Miui-SmoothCorner 的创建
android::uirenderer::skiapipeline::SmoothCorner::SmoothCorner() (diff = 700KB)


SystemUI 进程中渲染线程 RenderThread 在初始化启动的时候,发现比VIVO多一次 700KB 的大内存分配:为创建**SmoothCorner(MIUI圆角效果)**引入的相关内存,定位到源码如下:

责任人 @刘修全
原因分析:
SmoothCorner是美学需求驱动做的平滑圆角,在系统内的圆角矩形中大范围使用。关闭后则systemui 布局中无平滑圆角,体验上会有退坡。
更多的 VectorDrawable 使用
android::uirenderer::VectorDrawable::Path::Path (diff = 758KB )


示例1:
miui.systemui.controlcenter.panel.secondary.media.MediaPanelDelegate.initView
示例2:
com.android.systemui.miui.volume.VolumeColumn.updateIcon
示例3:
com.android.systemui.statusbar.StatusBarIconView.getIcon
原因分析:
小米的 SystemUI 中部分UI布局使用了SVG,包括控制中心媒体栏、音量条、状态栏图标等。为了启动速度优化,进行了UI的预加载处理,例如控制中心。因此在开机启动场景下,部分View,即使没有显示出来,也会提前创建(Inflate)。反观竞品,UI布局中未使用任何的 VectorDrawable。
MiuiSystemUI中 控制中心 预加载相关 commit:
https://gerrit.pt.mioffice.cn/c/platform/packages/apps/MiuiSystemUIPlugin/+/6407523