资源采集API特性指导

📅 2026/6/30 12:59:05
资源采集API特性指导
本原创文章帖发布在华为开发者联盟社区欢迎开发者前往访问评论交流更多与该内容相关讨论请点击原帖查看资源采集API特性指导-华为开发者话题 | 华为开发者联盟1、概述资源调优和资源泄漏是应用开发中常见且难以快速解决的两类棘手问题。在鸿蒙应用代码开发过程中这些问题通常难以利用常规调试手段如流水日志、/proc/[pid]/smaps、/proc/meminfo、/proc/memview、hidumper --mem直接定位和处理。表1 资源类型说明资源类型描述文件描述符通过open/fopen、epoll、eventfd、socket、pipe、dup等创建的fd。线程通过线程函数创建的线程如pthread_create。Native内存包含堆内存和映射区内存通过malloc/calloc/realloc/new分配的堆内存NativeHeap;通过mmap映射的映射区内存包含so等文件映射以及匿名映射GPU内存通过图形标准API如opengles、vlukan、opencl创建的纹理texture、缓冲区buffer等内存。全局句柄Global Handle在Native侧通过napi_create_reference创建的ArkTS对象全局引用napi_ref。为快速解决上述两类痛点问题鸿蒙系统通过Performance Analysis Kit开放的HiDebug资源采集接口OH_HiDebug_StartProfiler/ OH_HiDebug_StopProfiler提供线上资源分配栈采集功能赋能开发者高效实现问题的自诊断与自闭环。该资源采集接口性能功耗开销较大盲目或高频调用易触发应用卡顿、发热。集成时请务必谨慎评估开销建立严格的条件触发策略和配置合理的采集参数兼顾线上功能正常运行和性能开销的平衡。2、HiDebug资源分配栈采集接口介绍6.1版本资源采集接口API 24.0原型如下// 资源类型 typedef enum OH_HiDebug_ResourceType { OH_RES_TYPE_FD, OH_RES_TYPE_THREAD, OH_RES_TYPE_NATIVE, OH_RES_TYPE_GPU, OH_RES_TYPE_GLOBAL_HANDLE } OH_HiDebug_ResourceType; // 采集参数 typedef struct OH_HiDebug_ResProfilerConfig { uint32_t maxDuration; uint32_t filterSize; uint32_t maxStackDepth; uint32_t statisticsInterval; uint32_t sampleInterval; } OH_HiDebug_ResProfilerConfig; // 采集结果 typedef struct OH_HiDebug_ProfilingResult { OH_HiDebug_ResourceType resourceType; const char* filePath; } OH_HiDebug_ProfilingResult; // 采集结果回调函数 typedef void (*OH_HiDebug_ProfilingCallback)(OH_HiDebug_ProfilingResult* result); // 启动采集 HiDebug_ErrorCode OH_HiDebug_StartProfiler( OH_HiDebug_ResourceType type, OH_HiDebug_ResProfilerConfig* config, OH_HiDebug_ProfilingCallback callback); // 停止采集 HiDebug_ErrorCode OH_HiDebug_StopProfiler(void);2.1 资源分配栈采集接口资源类型参数简介type参数支持五类资源类型包括文件描述符FD、线程Thread、NativeHeap内存、GPU内存和全局句柄Global Handle。2.2 资源分配栈采集接口采集参数简介config采集参数支持五种配置项包括最大采集时间、过滤大小、最大栈深、统计间隔和采样大小。这些参数开发者可按需灵活配置调整实现资源分配栈采集的性能开销和应用体验之间的平衡。采样率参数仅针对Native内存生效。表2-2-1 采集参数说明采集参数描述说明maxDuration最大采集时间单位s。最大支持1小时。采集参数可根据实际采集开销情况调整达成性能损耗与应用体验的自适应平衡。默认值仅供参考。filterSize过滤≤filter_size的内存分配栈减少采集数据量。maxStackDepth用于设置最大资源分配调用栈回栈深度建议默认值30statisticsInterval统计间隔表示将一个统计周期内的栈进行汇总单位秒。建议默认值10s。sampleInterval采样大小单位字节。采样率1/采样大小。建议默认值384 bytes。注内存分配384字节按照1/384采样率采栈≥384字节的全采。2.3 资源分配栈采集接口回调参数简介callback回调参数包含资源分配栈.htrace文件沙箱路径filePath开发者可直接获取栈trace文件并上传云侧做泄漏根因分析、聚类。表2-3-1 回调参数说明回调参数描述resourceType采集资源类型。filePath资源分配栈.htrace文件沙箱路径。2.4 资源分配栈采集接口实现逻辑本质是对不同资源的分配/释放函数跟踪然后记录调用栈、去重、符号化并最终以.htraceprotobuf格式文件形式落盘至应用沙箱供IDE加载、解析和查看Call Trees辅助资源调优和资源泄漏问题快速定位。1文件描述符hook文件描述符打开和关闭函数并记录调用栈2线程hook线程的创建和销毁函数并记录调用栈3NativeHeap内存hook C库musl库 malloc/calloc/realloc/free、mmap/munmap函数并记录调用栈。4GPU内存hook opengles、vlukan、opencl的纹理texture、缓冲区buffer创建和释放函数并记录调用栈。5Global Handlehook global handle对象的创建和释放函数并记录调用栈。2.5 资源分配栈采集接口触发条件表2-5-1 资源分配栈采集接口OH_HiDebug_StartProfiler触发条件资源类型触发采集条件推荐值检测间隔推荐值参考建议文件描述符FD超过 5000 个60s1、开发者可通过读取/proc/self/fd_num节点获取被采集应用的FD总数。2、1个检测周期内每60s若发现应用的FD总数超过阈值5000个则认为可能存在FD泄漏此时可调用资源分配栈采集接口采栈。线程超过 700 个60s1、开发者可通过读取/proc/self/status节点的Threads字段获取被采集应用的线程总数。2、1个检测周期内每60s发现线程总数超过700个则认为可能存在线程泄漏此时可调用资源分配栈采集接口采栈。Native内存包含堆内存和映射区内存超过 3 GB200s1、开发者可通过读取/proc/self/status节点将VmRssVmSwap字段之和作为被采集应用占用的Native内存总量。注应用Native内存超4G且整机内存压力过大时可能触发系统管控建议超3G或更小时就启动采集。2、连续2个检测周期每200s一个周期Native内存均超过阈值3GB则认为可能存在Native内存泄漏此时可调用资源分配栈采集接口采栈。GPU内存超过 2300 MB60s1、开发者可通过调用OH_HiDebug_GetGraphicsMemory获取被采集应用的GPU内存总量。2、连续2个检测周期每60s一个周期GPU内存均超过阈值12G手机2.3GB则认为可能存在GPU内存泄漏此时可调用资源分配栈采集接口采栈。全局句柄Global HandleVM 堆内存使用率超过 70%60s1、开发者可通过hidebug.getAppVMObjectUsedSize() /hidebug.getAppVMMemoryInfo().totalHeap 0.7作为触发采集条件。2、1个检测周期内每60sVM堆内存使用率超过70%则认为可能存在Global Handle泄漏此时可调用资源分配栈采集接口采栈。3、API资源采集规格约束3.1 采集配额限制• 整机所有应用共享每日最多可采集4次同一时刻最高支持4个不同应用并行采集。• 应用单应用独享每日最多可采集2次同一时刻最高支持应用内2个进程并行采集。3.2 系统负载熔断机制当系统触发以下任一负载保护条件时API采集请求将被拒绝并返回相应错误码• CPU限制整机系统CPU占用率超过70%• 内存与存储限制整机系统剩余可用内存RAM或 剩余可用存储空间ROM低于影响应用体验和整机读写性能阈值。负载保护条件未来可能会随系统版本迭代持续优化具体以实际返回错误码为准。3.3 并发冲突约束本API与命令行工具或系统采集任务存在排他性。当与命令行工具或系统采集任务的请求发生冲突时API采集请求将被拒绝并返回相应错误码。3.4 采集结果交付• 存储路径采集到的调用栈日志文件.htrace将自动保存在应用沙箱目中路径为/data/storage/el2/base/files/• 日志文件名规则:“资源采集类型-进程名-进程号-时间戳.htrace”。3.5 注意事项• 受上述采集规格与约束限制本API不保证采集请求一定成功• 调用本API会对当前应用进程及整机性能功耗产生不可忽略的影响包括但不限于CPU、内存占用升高丢帧卡顿发热。开发者在集成时必须谨慎评估其性能功耗开销并建立严格的条件触发策略如仅在特定灰度范围内、应用资源超基线阈值时触发同时须配置合理的采集参数以兼顾性能功耗开销平衡再决策是否开启。严禁在线上环境下盲目或高频次触发。3.6 老化管控每种资源类型均受以下条件约束• 按文件个数管控只保存最新5份文件滚动老化• 按文件大小管控单文件上限1G。采集达上限即停止不做覆盖。避免单个文件太大撑爆磁盘且无法被IDE加载。• 按目录空间管控沙箱下采集文件存储空间超过4G上限删除最早的采集文件。• 按存储时效管控单个日志存储最大时长24小时。24小时到期后清理超时的采集文件。3.7 系统采集模式优先级规格• 命令行模式hdc shell hiprofiler_cmd优先可抢占其它采集模式API采集、系统采集、应用灰度采集• 在API采集OH_HiDebug_StartProfiler/StopProfiler和 系统采集/应用灰度采集模式同时并发时按照FIFO原则哪种模式先发起采集请求服务端就优先响应该模式其它模式拒绝访问。4、接口说明官方文档https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-hidebug-h#oh_hidebug_startprofiler附1 Global Handle常见泄漏场景场景一全局引用忘记delete最常见#include napi.h // 全局引用泄漏重灾区 static napi_ref g_my_ref nullptr; napi_value LeakRef(napi_env env, napi_callback_info info){ napi_value obj; napi_get_cb_info(env, info, nullptr, nullptr, obj, nullptr); // 创建强引用初始计数1 napi_create_reference(env, obj, 1, g_my_ref); // ❌ 只创建不释放 return nullptr; } // 缺少清理函数 // void Cleanup(napi_env env) { // if (g_my_ref) { // napi_delete_reference(env, g_my_ref); // g_my_ref nullptr; // } // }场景二循环/重复创建不释放叠加泄漏napi_value CreateAndLeak(napi_env env, napi_callback_info info) { napi_value obj; napi_get_cb_info(env, info, nullptr, nullptr, obj, nullptr); napi_ref ref; // 每次调用都新建引用 napi_create_reference(env, obj, 1, ref); // ❌ 无delete // 错误覆盖旧ref旧ref句柄永久丢失 // g_ref ref; return nullptr; }场景三类/实例持有引用、析构不清理class NativeHolder { public: napi_ref m_ref; NativeHolder(napi_env env, napi_value obj) { napi_create_reference(env, obj, 1, m_ref); } // ❌ 析构不delete ~NativeHolder() { // 缺少napi_delete_reference(env, m_ref)配对调用 } }; napi_value CreateHolder(napi_env env, napi_callback_info info) { napi_value obj; napi_get_cb_info(env, info, nullptr, nullptr, obj, nullptr); NativeHolder* holder new NativeHolder(env, obj); // 若不主动清理holder泄漏 m_ref泄漏 return nullptr; }