Systemui 开机native内存占用分析

来源飞书 wiki(obj_token: Ev3wdmqLCoZAZJxkFPCcrRuQneg)

注:本文档包含 16 张图片和 12 个嵌入式表格(sheet token HeASsftQAhzQAXtkh2pcgJpxnLb),所有图片因飞书下载权限 403 未能落地,已用 token 占位符替代;sheet 由飞书内联引用无法直链导出,已保留 block 标记。

关闭pipeline cache方案后,除了blob的两个symbols,vkCreatePipelineCache也会降10MB,内存分配共节省22MB,比率 35%。

除去pipeline影响8850内存 43MB左右,vivo 32MB,差值10MB。

📷 图片描述:图片展示了不同版本系统在特定函数调用下的内存占用情况。其中,vivo8750_iter1、SM8850f_iter1、SM8850s_iter1、SM8850t_iter1等版本在total、android::Bitmap::allocateHeapBitmap、sk_malloc_flags、android::uirenderer::RenderNode::RenderNode等函数调用下的内存占用数据。图片中以红色框突出显示了SM8850t_iter1版本在各函数调用下的内存占用数值。(token DhYCbeWrsoBxQ3xjG00cWHOlnxc,下载失败)

王月提供 systemui关闭mi feature方法:

  1. 将/product/etc/pipeline_infos目录下,com.android.systemui文件夹下的内容删除

📷 图片描述:图片展示的是在终端命令行中执行”ls /product/etc/pipeline_infos”命令后的输出结果。输出内容为一系列以”com.”开头的文件夹名称,如com.android.chrome、com.android.chrome.autofill等。(token Wqicb6NSYoqKngxA8tZc77p0nNe,下载失败)

  1. 执行如下命令后重启手机,复测systemui冷启动:
adb root
adb remount
adb reboot
adb root
adb remount

your_package_name=com.android.systemui
adb shell rm -rf //data/user_de/0/\$your_package_name/cache/
adb shell rm -rf //data/system/surfaceflinger/pipelinecache/\$your_package_name/
adb shell rm -rf //product/etc/pipeline_infos/\$your_package_name/

Perfetto trace行为:

initShaderDiskCache 函数包含BlobCache::set和 BlobCache::blob过程,执行时间从72ms降到4ms

📷 图片描述:图片展示的是Systemui进程的Perfetto trace界面。左侧为线程列表,显示了多个mem.native.thr.融合线程。右侧是时间轴,标注了不同函数的执行时间,如initShaderDiskCache函数执行时间为71ms,还有FileBlobCache、BlobCache::unflatten等函数的执行时间。(token MGkNbkrXooc1nUxvZqzcrHAOnfh,下载失败)

📷 图片描述:图片展示的是Perfetto trace分析界面,用于分析Systemui开机native内存占用问题。界面中以时间轴形式呈现了不同函数的执行情况,其中”InitShaderDiskCache”函数被红色框突出显示,其执行时间为3ms,耗时950us,内存占用260ms。(token LFrDbFMpzoonQzxc4grcsCXLnSe,下载失败)

内存分配行为:

📷 图片描述:图片展示的是SM8850迭代3次后的函数调用情况对比数据。其中,红色框突出显示了android::BlobCache::set和android::BlobCacheCache::Blob两个函数,其在SM8850迭代3次前后的大小变化分别为10992.769KB和1847.865KB,且在SM8850迭代3次后这两个函数的大小均大幅减少。(token V0yRb9Fs1o1au2xwkTrcbkPqnDb,下载失败)

修改后BlobCache::set 分配990KB

📷 图片描述:图片展示 addCriterion(token R4J9bAoAUoOSYFxWQLJcVUQzn1f,下载失败)

修改后BlobCache::Blob::Blob 分配65KB

📷 图片描述:图片展示的是Perfetto工具界面,用于分析systemui开机native内存占用。界面中以表格形式呈现了内存分配信息,关键部分是”sum(size)“数值,其数值为12997140,对应内存分配大小为12.997MB。(token B1mMbG7gtoad2jxTh8QchmiBnNc,下载失败)

列举如下top占用的symbol,总共9MB

sk_malloc_flags 差值 1.7MB

业务行为

📷 图片描述:图片展示的是Android系统中函数调用栈信息。左侧为函数名称,如android.graphics.FontBuilder.build等,右侧是对应的函数库名称,如libhwui.so等。中间列出了vivo8750_iter1_size和SM8850f_iter1_size的数值,以及size_diff_vivo8750_iter1_vs_SM8850f_iter1的差值。(token BK1KbSKrxokuOZxVNNXcmCYXnph,下载失败)

android::android_view_RenderNode_create 差值2.3MB

boot-framework.oat 调用栈

📷 图片描述:图片展示的是Android系统中调用栈信息。上方显示了两个函数调用路径,分别为”android::android_view_BorderNode::create_…”和”android::android_view_RenderNode::RenderNode…”,并标注了调用比例为0.1%。下方是大量函数调用信息,以”android::“开头,部分函数名被红色框突出显示。(token YmBFbJAQfoDH6SxuNR2ctUn9nkd,下载失败)

android::android_view_RenderNode_create 1MB

Systemui 业务行为

📷 图片描述:图片展示的是Systemui业务行为中android::android_view_RenderNode_create函数的调用栈信息。画面中以红色高亮显示了该函数的调用路径,从android.view.View.create_255处开始,依次经过android.graphics.Renderer.create等多级函数调用,最终到达android.widget.ImageView的init函数。(token PUo0b63R1opyFlxTNbFcWDkknwb,下载失败)

unknown 1MB

需要工具解析出具体调用栈

SkArenaAlloc::ensureSpace 1.5MB

vivo未分配,skia机制,同下面的addToAtlas相同调用栈链路,需要业务看下

📷 图片描述:图片展示了Systemui开机native内存占用分析中SkArenaAlloc::ensureSpace函数的调用栈信息。表格包含slice_id、ts、arg_set_id、mem_size、func_name、lib_name、stacktrace等列。其中,func_name为SkArenaAlloc::ensureSpace,lib_name为libhwui.so,stacktrace列以#0开头,显示了从SkArenaAlloc::ensureSpace到skgpu::gles3::AtlasTextOp::onPrepareDraws等函数的调用链路。(token YA2Sb56hnogbh5xfO1YcW7vEngh,下载失败)

📷 图片描述:图片展示了SkArenaAlloc::ensureSpace函数的调用栈信息。上方代码区域显示了该函数的定义及部分调用代码。下方调用栈列表中,SkArenaAlloc::ensureSpace函数被红色框突出显示,其调用栈包含多个函数,如android::uirenderer::RenderThread::run()等。(token Josebdwwoos3wuxNj9ccSMw3n4e,下载失败)

GrDrawOpAtlas::addToAtlas 1MB

vivo无此行为,需要业务看下

📷 图片描述:图片展示的是系统内存占用分析工具的界面,用于解析系统内存占用情况。界面中呈现了函数调用栈信息,包括函数名称、库名、vivo8750_iter1_size、SM8850f_iter1_size及size_diff_vivo8750_iter1_vs_SM8850f_iter1等数据。其中,SkArenaAlloc::ensureSpace和GrDrawOpAtlas::addToAtlas两个函数的内存占用分别为1.5MB和1MB。(token MT3BbQFrZoGpeZx6K7Xc1Mz5ngl,下载失败)

art::Thread::CreateNativeThread 800KB

小米业务行为

📷 图片描述:图片展示了调用art::Thread::CreateNativeThread函数的函数调用栈信息。上方显示函数名称及参数,右侧有”Search”搜索框。主体部分以黄色背景呈现函数调用关系,左侧有数字序号标识,右侧有函数名称、包名等信息。(token PWmvbcc2RoIwExxhMuTc7nFGnae,下载失败)

android::uirenderer::VectorDrawable::Path::Path,740kb

完全是systemui 业务行为

📷 图片描述:图片展示的是systemui开机native内存占用分析中,art::Thread::CreateNativeThread占用800KB的内存情况。界面中以表格形式呈现,包含函数名、库名、vivo8750_iter1_size、SM8850f_iter1_size、size_diff_vivo8750_iter1_vs_SM8850f_iter1等列。其中,art::Thread::CreateNativeThread函数在libart.so库中。(token XYQjbvUNvouipZxl4gZcDm68nXf,下载失败)

std::__1::__function::__func 680KB,像是mem use工具的占用

📷 图片描述:图片展示的是一个C++代码片段,代码中包含多个函数调用,如__func____PRETTY_FUNCTION__等,用于获取函数名。代码还涉及operator()operator()等操作符,以及operator newoperator delete等内存操作。(token EqJDbUZHvoSKnyxWkc3cx6Zsnlf,下载失败)