Android 15 新 API:内存追踪利器 ProfilingManager

2024-08-31 14:12

本文主要是介绍Android 15 新 API:内存追踪利器 ProfilingManager,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

android15-base-profiling.png

本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!

前言

我们都知道 Android Studio 里内置了 Profiler tool 供大家对 App 在 Memory、CPU、Network、Power 等角度进行 dump 和分析。

但如果一个内存相关的 bug 是运行时发生的,而且很难复现,那么后期就很难准确定位发生时的具体状况。

值得兴奋的是 Android 15 将直面这个痛点:引入了 ProfilingManager API,允许 app 对 Memory 进行动态的、随时随地的 dump。

生成的文件默认存在本地,也可以通过网络传递到 offboard,方便开发者事后回溯。

API 说明

ProfilingManager 主要提供了 3 个方法。

registerForAllProfilingResults

注册 profiling 请求的回调和执行的线程,需要如下两个参数:

ParametersDescriptions
executorExecutor: 回调执行的线程池实例,不可为空
listenerConsumer: 携带 profiling 结果的 listener 实例,不可为空

unregisterForAllProfilingResults

注销 profiling 请求的回调,如果没有指定 listener 参数的话,将移除所有 callback。

ParametersDescriptions
listenerConsumer: 待移除的回调,null 的话移除所有

requestProfiling

请求进行一次 profiling 操作,有非常详细的参数可供设置:

ParametersDescriptions
profilingTypeint: profiling 操作的类型,主要包括 dump Java 堆的 PROFILING_TYPE_JAVA_HEAP_DUMP,dump 堆的 PROFILING_TYPE_HEAP_PROFILE, dump 栈的 PROFILING_TYPE_STACK_SAMPLING 和 dump 系统 trace 的PROFILING_TYPE_SYSTEM_TRACE参数不能为空
parametersBundle: 携带请求额外的相关参数, 如果包含了未定义的参数类型,请求会失败,在 callback 当中以 ERROR_FAILED_INVALID_REQUEST 结果进行返回,参数可为空。
tagString: 回来识别 dump 输出的 tag 标签,其中的前 20 个字符将会以小写的形式拼接到 dump 文件名中,参数可为空
cancellationSignalCancellationSignal: 支持请求侧用来取消 dump 的 cancellation 实例,如果 dump 结果已出来的话,会被返回。参数可为空,此时将执行系统默认的超时时间,之后结束 dump。
executorExecutor: 回调执行的线程池实例,参数可为空。但如果没有其他 executor 注册的话,该请求会被无视。
listenerConsumer: 监听操作结果的实例,registerForAllProfilingResults() 注册的 callback 同样也会被回调,参数可为空。但如果没有其他 listener 注册的话,该请求会被无视。

需要说明的是

  • 很多时候,并不推荐直接使用该 API 进行 dump,相反可以采用 androidx 中封装好的高层级接口进行请求。该接口内部会依据可用选项和简化的参数进行正确地请求。
  • 并非所有情况都会得到响应
  • 需要同时考虑 result 的监听和执行它的线程池两个参数,要么都设置,要么都不设置交给 registerForAllProfilingResults() 一起设置

ProfilingResult

在上述提到的 registerForAllProfilingResults() 里会回调 ProfilingResult 参数过来,它用来封装单次请求 profiling 操作的结果。

主要提供了这几个方法来获得信息:

  • getErrorCode():获取 profiling 请求失败的原因,如果成功的话,值为 ERROR_NONE 即 0,其他的还有 ERROR_FAILED_RATE_LIMIT_SYSTEM 等值
  • getErrorMessage():获取额外的失败信息
  • getTag():请求时传入的参数 tag,方便回溯
  • getResultFilePath():获取 profiling 结果文件的路径

实战

留意一下,需要将 Android 15 的 SDK 升级到 revision 3 才可以看到该 API。

class ProfilingActivity : AppCompatActivity() {private val singleThreadExecutor = Executors.newSingleThreadExecutor()private val profilingResultConsumer = Consumer<ProfilingResult> {Log.d(TAG_PROFILING, "accept profilingResult:${it.printProfilingResult()}")}private val profilingManager by lazy {getSystemService(ProfilingManager::class.java)}override fun onCreate(savedInstanceState: Bundle?) {...binding.dump.setOnClickListener {Log.d(TAG_PROFILING, "button dump tapped")profilingManager.registerForAllProfilingResults(singleThreadExecutor,profilingResultConsumer)}binding.request.setOnClickListener {Log.d(TAG_PROFILING, "button request tapped")profilingManager.requestProfiling(// ProfilingManager.PROFILING_TYPE_SYSTEM_TRACE,// ProfilingManager.PROFILING_TYPE_JAVA_HEAP_DUMP,// ProfilingManager.PROFILING_TYPE_STACK_SAMPLING,ProfilingManager.PROFILING_TYPE_HEAP_PROFILE,null,"TEST_FOR_PROFILING_MANAGER",null,singleThreadExecutor,profilingResultConsumer)}binding.stop.setOnClickListener {Log.d(TAG_PROFILING, "button stop tapped")profilingManager.unregisterForAllProfilingResults(profilingResultConsumer)}}}

可以看到我们在代码里设置的 tag 为 “TEST_FOR_PROFILING_MANAGER”

转存失败,建议直接上传图片文件

我们点击 “register dump profile” button 开始注册回调,然后点击 “request dump profile” button 开始请求。

看下 Profiling 的 log 输出。

点击完 request 之后需要等待一段时间(系统默认的 dump 超时为 120s 左右)才会看到 dump 结果。

注意,不要重复点击,否则会收到如下错误的 callback。其中 3 对应的是 *ERROR_FAILED_PROFILING_IN_PROGRESS*,表示仍在 dump 中,该重复请求被拒绝。

ProfilingResult{errorCode:3 errorMessage:null resultFilePath:null tag:TEST_FOR_PROFILING_MANAGER}

下面我们以如下 4 种 dump 类型看下具体的 ProfilingResult 输出内容。

PROFILING_TYPE_JAVA_HEAP_DUMP

04-21 19:37:32.220  7184  7270 D Profiling: accept profilingResult:ProfilingResult{errorCode:0 errorMessage:null resultFilePath:/data/user/0/com.ellison.osvdemo/files/profiling/profile_testforprofilingmana_2024-04-21-19-37-26.perfetto-java-heap-dump tag:TEST_FOR_PROFILING_MANAGER}

可以看到成功输出了 Java heap 的 dump 文件,并且咱们的 tag 被拼接到了文件名中,而且将_删除并限制了 20 的长度。

所以咱们设置的 tag 最好不要包含字母以外的字符,并且不要过长,不然不方便定位 tag。

PROFILING_TYPE_HEAP_PROFILE

04-21 19:47:16.810  7474  7552 D Profiling: accept profilingResult:ProfilingResult{errorCode:0 errorMessage:null resultFilePath:/data/user/0/com.ellison.osvdemo/files/profiling/profile_testforprofilingmana_2024-04-21-19-45-11.perfetto-heap-profile tag:TEST_FOR_PROFILING_MANAGER}

和上面的 Java dump 一样,成功输出了 heap 全量的 dump 文件。

PROFILING_TYPE_STACK_SAMPLING

04-21 19:53:01.043  7704  7790 D Profiling: accept profilingResult:ProfilingResult{errorCode:0 errorMessage:null resultFilePath:/data/user/0/com.ellison.osvdemo/files/profiling/profile_testforprofilingmana_2024-04-21-19-51-55.perfetto-stack-sample tag:TEST_FOR_PROFILING_MANAGER}

dump stack 的记录也是一样,不再赘述。

PROFILING_TYPE_SYSTEM_TRACE

04-21 15:43:33.926  4730  4775 D Profiling: accept profilingResult:ProfilingResult{errorCode:7 errorMessage:Trace is not supported until redaction lands resultFilePath:null tag:null}

和前面 3 中 type 不同,这种 dump 系统 trace 的请求总是会直接失败。

ProfilingResult 结果对应的 errorCode 为 7,常量名称为 ERROR_FAILED_INVALID_REQUEST,表示请求失败了:这是一个不合法的 ProfilingRequest。

The request failed due to invalid ProfilingRequest.

单从这个 error 定义来看,压根不知道问题出在哪。

在 API 章节里我们提到过,如果调用 requestProfiling() 时传递的 Bundle 参数包含了不支持的 key-value,会造成 ERROR_FAILED_INVALID_REQUEST 错误。

但可以看到:实际上咱们的 DEMO 代码里啥 bundle 都没携带,所以应该不是这个原因。

好在,ProfilingRequest 结果还打携带了 errorMessage,其内容为:Trace is not supported until redaction lands

笔者尝试依据该 message 找到蛛丝马迹,但无论在 Android 官网,还是在 Android 源码里,抑或是在 AOSP issue 的首页上,都没找到合相关的记录。

我猜测是 PROFILING_TYPE_SYSTEM_TRACE 需要某个 DOC 里没说明的 Bundle 参数,造成了失败。当然也有可能是 beta 版阶段的系统 bug。

后续再看。

perfetto 支持

以 PROFILING_TYPE_JAVA_HEAP_DUMP 的文件为例,从 data 目录里 pull 之后,在 ui.perfetto.dev 中打开,可以进行分析。

转存失败,建议直接上传图片文件

DEMO 源码

AndroidOSVDemo

结语

ProfilingManager API 允许 App 直接进行各种 Memory 数据的 dump,相信这能在一定程度上帮助开发者进行内存相关问题的回溯,不再像以前那样被动。

从上面的实战也能看到目前部分功能还存在些问题,期待正式版本能够修复。

感兴趣的朋友可以在 Android 15 稳定版的时候再行体验。

笔者猜测因为 Memory 是最高优的关注点,所以目前 ProfilingManager 只支持 dump Memory。但我相信随着该 API 的成熟和普及,以及确实有 dump 其他点强劲需求的话,肯定会逐步支持更多 dump 的内容。

参考资料

  • ProfilingManager
  • ProfilingResult

这篇关于Android 15 新 API:内存追踪利器 ProfilingManager的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1124126

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

键盘快捷键:提高工作效率与电脑操作的利器

键盘快捷键:提高工作效率与电脑操作的利器 在数字化时代,键盘快捷键成为了提高工作效率和优化电脑操作的重要工具。无论是日常办公、图像编辑、编程开发,还是游戏娱乐,掌握键盘快捷键都能带来极大的便利。本文将详细介绍键盘快捷键的概念、重要性、以及在不同应用场景中的具体应用。 什么是键盘快捷键? 键盘快捷键,也称为热键或快捷键,是指通过按下键盘上的一组键来完成特定命令或操作的方式。这些快捷键通常涉及同

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目