资讯详情

资讯详情

【ArkUI提高练中学】第7课:性能调优与稳定性治理

本节目标掌握卡顿丢帧的根因分析方法能够使用 Frame 模板、ArkUI 模板和 ArkUI Inspector 精准定位 UI 渲染瓶颈掌握 ArkTS 内存泄漏的检测与定位方法能够使用 JSLeakWatcher 生成泄漏报告并分析引用链掌握 AppFreeze 冻屏故障的分析方法能够解读冻屏日志中的 THREAD_BLOCK_6S、APP_INPUT_BLOCK 等关键信息掌握崩溃的异常处理分层模型能够建立 try-catch、Promise.catch、全局异常监听的纵深防御掌握资源泄漏的运行态检测能力能够使用 HiDebug 采集 FD、线程、Native 内存等资源分配栈掌握线上性能监控方案能够使用 HiAppEvent 订阅故障事件并结合 APMS 进行多维度分析掌握 FaultLogExtensionAbility 的延迟通知机制能够处理应用崩溃/冻屏后未及时启动的故障补报场景能够为应用建立“开发态检测 → 运行态监控 → 线上告警 → 修复验证”的全链路稳定性治理闭环一、卡顿丢帧的根因分析1.1 卡顿丢帧的故障模型屏幕以固定频率发送 Vsync 信号来控制每一帧绘制操作的时机。以 120Hz 刷新率为例每帧平均耗时 8.33ms。应用侧收到 Vsync 信号后响应用户输入事件确定 UI 元素的位置、大小、资源、动效属性等然后提交绘制指令给渲染服务Render Service渲染服务根据绘制指令进行图形计算和渲染操作将渲染结果写入帧缓冲区最终送到屏幕上显示。按上述流程应用侧和 Render Service 侧都可能因为处理时间较长超过了 Vsync 信号周期导致界面送显的频率低于屏幕刷新率出现卡顿丢帧的情况。前者可能是应用业务逻辑、组件复杂、执行耗时逻辑等导致后者可能是界面结构过于复杂、GPU 负载过大等导致。关键指标帧率稳定 60 帧最低不低于 45 帧单帧耗时120Hz 下不超过 8.33ms60Hz 下不超过 16.67ms丢帧率连续丢帧超过 3 帧即可感知卡顿1.2 用 Frame 模板定位卡顿使用 DevEco Profiler 的 Frame 模板抓取滑动翻页过程的 Trace 信息。常见 Trace 关键字H:touchEventDispatch屏幕触摸事件H:FrameNode[组件名][id:组件ID]::RenderTask执行单个组件的绘制任务H:ReceiveVsync应用接收 Vsync 信号排查思路先看帧级耗时再分流到 UI 主线程或渲染线程。如果H:ExecuteJS、FlushDirtyNodeUpdate、Measure/Layout/Create耗时长说明是主线程问题需优化 ArkTS 和组件刷新。如果RSUniRenderThread单帧长、纹理创建/大图耗时说明是渲染侧问题需降低图片尺寸、避免动画中频繁模糊/裁剪/阴影。1.3 用 ArkUI 模板分析组件与状态ArkUI 模板用于定位由于组件耗时、页面布局、状态变量更新导致的卡顿问题。常见场景布局嵌套过多引起的性能问题数据结构设计不合理应用使用一个较大的 Object在更新时只更新某些属性导致其他没变化的属性也会更新产生冗余刷新父组件中的子组件重复绑定同一个状态变量进行更新未正确使用装饰器如错误使用Prop传递一个大的对象进行深度拷贝通过ArkUI Component 泳道可以直观感知组件绘制频率、耗时等统计情况Summary 区域展示绘制次数、总耗时、最小耗时、平均耗时、最大耗时、耗时标准差。通过ArkUI State 泳道可以查看录制过程中发生的状态变量变化定位到可能造成卡顿的状态变量变化时间点框选对应时间段后查看对应组件刷新时间。1.4 完整案例分析Canvas 绘制频率过低导致翻页掉帧问题现象阅读文档场景下左右滑动翻页时丢帧帧率低。定位过程使用 DevEco Profiler Frame 模板抓取滑动翻页过程的 Trace 信息。查看 render_service 泳道确认当前屏幕刷新率为 120Hz但通过 Present Fence 可看到左右翻页时页面变化的帧率接近 20fps。在 Slice List 中通过 RenderTask 关键字过滤发现有应用执行 Canvas 组件的绘制任务。使用 ArkUI Inspector 查看应用布局确认应用采用 Canvas 组件来显示文档。根据 ArkUI Inspector 获取的 Canvas 组件 id 号在 Profiler 中搜索H:FrameNode[Canvas][id:2321]::RenderTask确认应用两次执行 Canvas 组件绘制任务的时间间隔为 50ms 左右正好是 20fps。分析结论应用组件绘制的频率过低小于屏幕刷新率导致丢帧问题。修改建议优化组件绘制的相关业务逻辑提高组件绘制的频率可参考 Drawing 自绘制性能提升。二、ArkTS 内存泄漏的精准定位2.1 内存泄漏的危害在 ArkTS 开发中若一个 ArkTS 对象不再需要但仍被某个引用链“意外”持有则垃圾回收器无法回收该内存从而导致内存泄漏。危害包括性能方面应用占用内存持续增长系统为释放内存会频繁触发 GCGC 执行时会暂停应用主线程Stop-The-World 机制导致界面卡顿、滑动不流畅。内存方面若泄漏内存持续积累并达到 ArkTS Local 堆/共享堆或进程的 OOM 上限阈值时则会产生 JS Crash。功耗方面系统频繁 GC 会消耗大量 CPU 资源持续高占用会导致设备发热加速电量消耗。功能方面部分泄漏会因对象引用残留间接导致功能异常。2.2 JSLeakWatcher 检测原理HarmonyOS 提供了 ArkTS 内存泄漏检测能力 JSLeakWatcher开发者可轻松接入相关 API实现对系统内具有生命周期的 ArkTS 组件对象定期执行泄漏自检测。检测流程应用在启动后调用enableLeakWatcher()接口开启检测功能。检测框架创建FinalizationRegistry对象用于监控系统内具有生命周期的 5 类常见 ArkTS 组件对象元能力-Ability、窗口-Window、NodeContainer、XComponent、自定义组件-CustomComponent并注册生命周期结束回调函数。添加异步定时 GC 任务每 90 秒执行一次 FullGC 操作同时添加定时 dump 任务FullGC 执行 5 秒后执行一次泄漏检测。尝试去解除引用的组件对象会被记录在列表 list1 中被销毁的组件在被 GC 时GC 的回调函数会将该对象记录在 list2 中list1 - list2 就是泄漏对象。2.3 常见泄漏原因Native 层强引用在 Node-API 中对 ArkTS 对象创建了持久化强引用。闭包捕获内部函数持有对外部作用域 ArkTS 对象的引用即使外部作用域已退出。全局或模块级缓存使用 Map、Array 缓存长期持有 ArkTS 对象。2.4 引用链分析方法当检测到泄漏时JSLeakWatcher 会生成泄漏信息文件*.rawheap文件和*.jsleaklist文件将这两个文件导入 IDEDevEco Studio 6.0.0 起均支持就可以获取泄漏对象列表。通过泄漏对象列表中的泄漏对象直接跳转到引用链加速找到持有该泄漏对象的根 GC_ROOT。判断真泄漏还是正常未释放退出页面后等待异步回调结束连续进入/退出 35 次。在 Snapshot 中导入 JsLeakWatcher 的.jsleaklist查看对象从 GC Root 到该对象的引用链。重点查全局单例/缓存、定时器、事件订阅、回调闭包等。2.5 修复示例定时器未清理导致泄漏// ❌ 泄漏写法页面销毁时未清理定时器EntryComponentstruct LeakPage{privatetimerId:number-1;aboutToAppear():void{this.timerIdsetInterval((){console.log(tick);},1000);}build(){Column(){Text(泄漏示例)}}}// ✅ 修复写法在 aboutToDisappear 中清理EntryComponentstruct FixedPage{privatetimerId:number-1;aboutToAppear():void{this.timerIdsetInterval((){console.log(tick);},1000);}aboutToDisappear():void{if(this.timerId!-1){clearInterval(this.timerId);this.timerId-1;}}build(){Column(){Text(修复示例)}}}三、AppFreeze 冻屏故障分析3.1 AppFreeze 检测机制AppFreeze应用冻屏是一种看门狗机制。当应用主线程被长时间阻塞无法及时响应用户输入或系统调度时系统会强制终止该应用。AppFreeze 主要包含两种核心检测机制THREAD_BLOCK_6S应用主线程卡死超时。APP_INPUT_BLOCK用户输入响应超时。检测原理是当用户对设备进行操作时多模输入服务会将事件派发给应用如果应用的主线程在收到输入事件后超过 5 秒仍未反馈处理结果系统认为该应用无法响应用户输入触发输入阻塞故障。3.2 冻屏日志三步定位法第一步确认故障类型与时间差打开日志文件首先查看日志头部的 Reason 字段确认是哪种机制触发。接着在日志中搜索 THREAD_BLOCK_6S 的日志段落找到 mainHandler dump 区域对比当前任务开始时间与日志抓取检测时间。若差值接近或超过 6 秒说明是当前正在运行的任务耗时过长若差值很小需要排查主线程是否积压大量任务。第二步排查消息队列积压查看日志中 Event runner 下方的队列统计信息检查高优先级事件数量。如果 High events 数量超过 400 或总事件数异常巨大说明业务代码在短时间内发送了大量高优先级任务导致主线程被占满。第三步分析主线程堆栈找到日志中 Tid 与应用进程 ID 一致的线程堆栈根据栈顶函数判断卡死原因。常见场景IPC 通信阻塞栈顶出现 Binder 通信相关函数。等锁卡死栈顶出现pthread_mutex_lock等锁相关函数。业务代码耗时/死循环栈顶直接指向开发者的.ets或.ts文件代码行。3.3 锁竞争案例采样栈定位在使用 Worker 或 TaskPool 进行并行计算时如果多个子线程竞争同一个全局锁会导致子线程执行变慢进而拖慢等待子线程的主线程最终引发冻屏。通过对比 THREAD_BLOCK_3S 和 THREAD_BLOCK_6S 两次堆栈快照可以发现3S 时主线程在执行业务逻辑处于运行态。6S 时主线程状态变为 SSleeping栈顶出现pthread_join和std::__n1::thread::join说明主线程在等待子线程完成而子线程因为锁竞争执行变慢最终拖垮了主线程。通过采样栈可以识别“频繁等锁”的故障模式精准定位到业务代码中的锁竞争问题。四、崩溃与异常处理体系4.1 崩溃的三类根因在 HarmonyOS 中进程被系统强制终止崩溃的原因通常有三类未捕获异常最常见的JS/ArkTS 抛异常但没人 catch。Native 层错误如 C 野指针、内存越界导致 Segmentation Fault。系统资源问题内存 OOM、线程爆炸。4.2 异常处理分层模型HarmonyOS 的异常处理可以理解为三层保护应用层try-catch、Promise.catch、全局异常监听。Runtime 层ArkTS/JS 引擎负责异常传播和崩溃收集。系统层内核最终决定是否 kill 进程。关键原则开发者唯一能控制的是“异常发生后能不能接住”。4.3 四层兜底防御实战基础防御try-catch90% 的崩溃都是因为“懒得写 try-catch”。在可能抛出异常的代码块中包裹 try-catch捕获后记录日志或降级处理。try{constdataJSON.parse(response);this.processData(data);}catch(err){console.error(解析失败:,err);this.showFallbackUI();}Promise 异常捕获异步请求必须写.catch()否则异常会直接导致未捕获异常崩溃。fetchData().then(datathis.handleData(data)).catch(err{console.error(请求失败:,err);this.showErrorToast();});全局异常监听使用errorManager.on(error, callback)注册全局错误监听这是最后一道防线确保任何未被捕获的异常都能被记录。import{errorManager}fromkit.AbilityKit;errorManager.on(error,(err:Error){console.error(全局异常:,err.message,err.stack);// 上报到监控平台reportError(err);});Ability 生命周期异常处理在onCreate、onForeground、onBackground等生命周期回调中包裹 try-catch因为这些地方一旦崩溃用户连界面都看不到。五、资源泄漏的运行态检测5.1 HiDebug 资源采集能力HarmonyOS 6.1 带来的 HiDebug 资源采集 API通过 Performance Analysis Kit 开放的OH_HiDebug_StartProfiler/OH_HiDebug_StopProfiler应用可以在合适条件下采集资源分配栈把“感觉有泄漏”变成“这里有证据”。支持的资源类型文件描述符通过 open/fopen、epoll、eventfd、socket 等创建的 FD。线程通过pthread_create创建的线程。Native 内存通过 malloc/calloc/realloc/new 分配的堆内存以及 mmap 映射的内存。GPU 内存通过 OpenGL ES、Vulkan、OpenCL 等创建的纹理和缓冲区。全局句柄Native 侧通过napi_create_reference创建的 ArkTS 对象全局引用。5.2 资源泄漏排查思路线上资源问题往往很隐蔽开发者能看到“应用越跑越卡”“内存曲线一路抬头”“线程数不知不觉变多”“FD 数量悄悄逼近上限”等现象但要回答“是谁分配的”“从哪条调用链来的”“为什么没释放”光靠流水日志往往不够。使用 HiDebug 资源采集 API 时type参数用于选择采集资源类型你怀疑谁不老实就先把观察镜头对准谁。config参数中的采集参数需要平衡“有用”和“别太打扰用户”之间的关系maxDuration控制采集时长maxStackDepth控制采集栈深度sampleInterval控制采样间隔。5.3 资源泄漏修复示例// ❌ FD 泄漏打开文件后未关闭constfilefileIo.openSync(path,fileIo.OpenMode.READ_ONLY);constcontentfileIo.readSync(file.fd,buffer);// 忘记 closeSync(file)// ✅ 修复使用 try-finally 确保关闭constfilefileIo.openSync(path,fileIo.OpenMode.READ_ONLY);try{constcontentfileIo.readSync(file.fd,buffer);}finally{fileIo.closeSync(file);}六、线上性能监控与告警6.1 HiAppEvent 事件订阅在应用初始化阶段注册观察者订阅应用冻屏、崩溃和资源超限事件。推荐使用sceneRunId将同一次复现统一关联按“场景脚本 → 主动采样 → 系统故障事件 → external_log → Profiler/Trace 证据 → 修复后同脚本复测”串起来。import{hiAppEvent,hilog}fromkit.PerformanceAnalysisKit;constDOMAIN:number0x1200;constTAG:stringStabilityWatcher;exportfunctionregisterStabilityWatcher():void{hiAppEvent.addWatcher({name:stability_watcher_v1,appEventFilters:[{domain:hiAppEvent.domain.OS,names:[hiAppEvent.event.APP_FREEZE,hiAppEvent.event.APP_CRASH,hiAppEvent.event.RESOURCE_OVERLIMIT]}],onReceive:(domain:string,groups:ArrayhiAppEvent.AppEventGroup):void{groups.forEach((group:hiAppEvent.AppEventGroup){group.appEventInfos.forEach((info:hiAppEvent.AppEventInfo){constlogPaths:stringJSON.stringify(info.params[external_log]??[]);hilog.info(DOMAIN,TAG,fault domain%{public}s name%{public}s time%{public}s logs%{public}s,domain,info.name,String(info.params[time]??),logPaths);// 实际项目在这里把元数据写入本地待上报队列不要读取或上传用户内容});});}});}注意事项APP_CRASH 本身不能证明 OOM要解析 external_log 中的 jscrash确认OutOfMemoryError或看 RESOURCE_OVERLIMIT 的resource_type是否为js_heap。处理完外部日志要及时归档/删除官方事件目录有容量上限若log_over_limittrue本次日志可能未成功生成。6.2 固定脚本复现与内存基线建立四条独立脚本进行系统化复现前台/后台切换 100 次每轮停留时间固定。弱网下请求超时、取消、重试 200 次记录并发数和未完成请求数。同一核心路径运行 28 小时每 5 分钟采样一次。加入多个应用驻留制造系统内存压力。每轮记录 ArkTS heap、native heap/PSS、Graphic/DMA、线程数、FD 数、Web/XComponent/播放器实例数、请求队列长度。多应用压力会改变 GC 和系统回收时机只有在相同场景结束并完成 GC 后基线仍随轮次单调增长才有泄漏证据。推荐用线性回归记录 MB/100 轮不要只比较峰值。6.3 APMS 故障指标APMS 基于应用现网运行的真实数据端侧故障事件实时上报、云侧统计分析为开发者提供崩溃、冻屏、应用终止、OOM、资源泄漏等常见故障的多维度指标数据。故障指标入口在 AppGallery Connect 开发与服务/质量/APMS/故障指标。APMS 提供的故障指标分类崩溃CPP_CRASH / JS_ERROR应用冻屏THREAD_BLOCK_6S / APP_INPUT_BLOCK / LIFECYCLE_TIMEOUT应用终止THREAD_THRESHOLD_KILLER 等OOM/资源泄漏THREAD_LEAK / MEMORY_LEAK / FD_LEAK指标页面提供四块功能指标查询过滤项包括应用版本、系统版本、设备型号、崩溃类型、时间范围支持天/小时/分钟维度。版本对比当前版本与对比版本的指标对比。维度分布应用版本、系统版本、设备型号的分布确定问题发生应用版本或高频发生的系统版本与设备型号。TOP 问题汇总异常日志形成问题列表可跳转至故障分析进行问题定位。6.4 FaultLogExtensionAbility 延迟通知从 API version 21 开始可以在 FaultLogExtensionAbility 中使用 HiAppEvent 事件订阅接口实现应用故障事件仅包括崩溃事件和应用冻屏事件的延迟通知。应用因崩溃或冻屏退出后无法启动或长时间未启动的场景下可以不依赖应用启动实现故障事件信息的订阅回调。工作原理主进程启动后添加事件观察者 A包含正常回调处理函数和事件观察者 B空实现仅用于生成过滤条件。两个观察者的订阅过滤条件被保存到应用沙箱中。应用发生故障后系统采集故障信息并保存到沙箱。若应用及时重启由观察者 A 处理若应用未及时重启系统在故障发生后 30 分钟拉起 FaultLogExtensionAbility 进程该进程中添加与 B 同名的事件观察者并实现正常回调处理沙箱中未回调的故障事件。约束FaultLogExtensionAbility 被拉起后只有 10 秒的时间用以完成故障处理超时未处理完成可以在onDisconnect中保存状态。从开机或上次拉起 FaultLogExtensionAbility 后应用首次触发崩溃或冻屏开始计时30 分钟内事件均不会重新计时。七、多元化习题习题 1判断题题目在 ArkUI 中AppFreeze 的 THREAD_BLOCK_6S 机制表示应用主线程卡死超过 6 秒系统会强制终止该应用。答案正确解读AppFreeze 是一种看门狗机制。当应用主线程被长时间阻塞无法及时响应用户输入或系统调度时系统会强制终止该应用。THREAD_BLOCK_6S 表示应用主线程卡死超时是 AppFreeze 最常见的检测机制。习题 2单选题题目以下哪个工具可以用于分析 ArkTS 状态变量的变化定位因冗余刷新导致的卡顿问题A. HiDebugB. JSLeakWatcherC. ArkUI 模板的 ArkUI State 泳道D. FaultLogExtensionAbility答案C解读ArkUI 模板的 ArkUI State 泳道可以查看录制过程中发生的状态变量变化包括状态变量名称、变化次数、状态变量类型、所属组件和所属类定位到可能造成卡顿的状态变量变化时间点。HiDebug 用于资源泄漏检测JSLeakWatcher 用于内存泄漏检测FaultLogExtensionAbility 用于故障事件的延迟通知。习题 3多选题题目关于 JSLeakWatcher以下说法正确的有多选A. JSLeakWatcher 可以监控 Ability、Window、NodeContainer、XComponent 和自定义组件五类对象B. JSLeakWatcher 通过 FinalizationRegistry 机制注册组件对象的 GC 回调C. JSLeakWatcher 检测到泄漏后生成 rawheap 和 jsleaklist 文件D. JSLeakWatcher 的 FullGC 默认每 60 秒执行一次答案A、B、C解读JSLeakWatcher 监控的 5 类对象包括元能力-Ability、窗口-Window、NodeContainer、XComponent、自定义组件-CustomComponent选项 A 正确。检测框架创建 FinalizationRegistry 对象用于监控系统内具有生命周期的 5 类常见 ArkTS 组件对象选项 B 正确。检测到泄漏后会生成泄漏信息文件包括 rawheap 文件和 jsleaklist 文件选项 C 正确。FullGC 默认每 90 秒执行一次不是 60 秒选项 D 错误。习题 4代码填空题题目请补全以下 AppFreeze 日志分析代码判断主线程是否因当前任务耗时过长导致卡死。// 在 AppFreeze 日志中搜索 THREAD_BLOCK_6S 段落// 找到 mainHandler dump 区域// 对比 Current Running: start at ... 与 EventHandler dump begin curTime: ...// 若差值接近或超过 6 秒说明是当前正在运行的任务耗时过长// 若差值很小需要排查主线程是否 ______________答案积压大量任务导致调度不及时解读AppFreeze 日志分析中如果当前任务开始时间与日志抓取检测时间的差值接近或超过 6 秒说明是当前正在运行的任务耗时过长直接导致卡死。如果差值很小如 1 秒内说明当前任务并未超时需要排查主线程是否积压大量任务导致调度不及时。习题 5代码改错题题目以下代码在异常处理方面存在不足请指出问题并完善。asyncfunctionfetchUserData(userId:string):PromiseUserData{constresponseawaithttpRequest(/api/user/${userId});constdataJSON.parse(response);returndataasUserData;}答案该代码存在两个问题HTTP 请求没有错误处理JSON 解析可能因数据格式异常抛出未捕获异常。完善如下asyncfunctionfetchUserData(userId:string):PromiseUserData|null{try{constresponseawaithttpRequest(/api/user/${userId});if(!response){console.error(请求返回为空);returnnull;}constdataJSON.parse(response)asUserData;returndata;}catch(err){console.error(获取用户数据失败:,err);returnnull;// 降级返回 null由调用方处理}}解读90% 的崩溃都是因为“懒得写 try-catch”。异步请求和 JSON 解析都必须做好异常处理捕获后记录日志或降级处理避免未捕获异常直接导致崩溃。习题 6简答题题目简述 AppFreeze 冻屏日志的三步定位法以及每一步的核心目的。答案AppFreeze 冻屏日志的三步定位法为第一步确认故障类型与时间差。打开日志文件查看 Reason 字段确认触发机制搜索 THREAD_BLOCK_6S 段落对比当前任务开始时间与日志抓取检测时间。目的是判断是当前任务耗时过长还是主线程任务积压。第二步排查消息队列积压。查看 Event runner 下方的队列统计信息检查高优先级事件数量。目的是确认是否存在业务代码在短时间内发送大量高优先级任务导致主线程被占满。第三步分析主线程堆栈。根据栈顶函数判断卡死原因区分 IPC 通信阻塞、等锁卡死、业务代码耗时/死循环等场景。目的是找到导致主线程阻塞的具体根因。解读三步定位法的核心逻辑是“先判断方向再排查积压最后定位根因”。从日志的时间差判断是单任务耗时还是任务积压再通过堆栈分析找到具体的阻塞点。习题 7简答题题目简述如何建立“开发态检测 → 运行态监控 → 线上告警 → 修复验证”的全链路稳定性治理闭环。答案全链路稳定性治理闭环包括四个环节开发态检测使用 DevEco Profiler 的 Frame/ArkUI 模板分析卡顿丢帧使用 JSLeakWatcher 检测内存泄漏使用 ArkUI Inspector 排查布局层级问题。运行态监控在应用初始化阶段注册 HiAppEvent 观察者订阅 APP_FREEZE、APP_CRASH、RESOURCE_OVERLIMIT 等事件使用 HiDebug 采集 FD、线程、Native 内存等资源分配栈通过固定脚本定期复现并记录内存基线。线上告警使用 APMS 故障指标进行多维度分析包括指标查询、版本对比、维度分布和 TOP 问题汇聚识别崩溃率、冻屏率、OOM 等指标的趋势变化。修复验证使用同一脚本复测对比修复前后的指标数据确认问题已解决且未引入新问题。四个环节形成从本地到线上、从手动到自动的完整治理体系。解读稳定性治理不是一次性的优化行为而是贯穿开发全流程的持续实践。核心在于将稳定性验证自动化、常态化在性能退化早期就发现并修复问题而非等到用户反馈后再排查。习题 8简答题题目简述 HiDebug 资源采集 API 支持的资源类型以及如何利用它排查资源泄漏。答案HiDebug 资源采集 API 支持五种资源类型文件描述符通过 open/fopen、epoll、eventfd、socket 等创建的 FD、线程通过 pthread_create 创建的线程、Native 内存通过 malloc/calloc/realloc/new 分配的堆内存以及 mmap 映射的内存、GPU 内存通过 OpenGL ES、Vulkan、OpenCL 等创建的纹理和缓冲区、全局句柄Native 侧通过 napi_create_reference 创建的 ArkTS 对象全局引用。排查资源泄漏时通过OH_HiDebug_StartProfiler/OH_HiDebug_StopProfiler采集资源分配栈type参数选择怀疑的资源类型config参数控制采集时长、栈深度和采样间隔。采集结果可以显示资源的分配调用栈从而定位到具体是哪段代码分配了未释放的资源。解读HiDebug 资源采集的核心价值在于将“感觉有泄漏”变成“这里有证据”。通过采集分配栈开发者可以精准定位到泄漏资源的分配位置大幅缩短排查时间。八、本节知识点总结卡顿丢帧根因分析使用 Frame 模板定位连续丢帧帧通过 H:ExecuteJS / FlushDirtyNodeUpdate 判断主线程问题通过 RSUniRenderThread / 纹理判断渲染侧问题。使用 ArkUI 模板分析组件绘制耗时和状态变量变化定位冗余刷新。ArkUI Inspector 用于排查布局层级问题。ArkTS 内存泄漏检测JSLeakWatcher 通过 FinalizationRegistry 机制监控 5 类 ArkTS 组件对象每 90 秒执行 FullGC生成 rawheap 和 jsleaklist 文件。导入 IDE 后可查看泄漏对象列表和引用链。常见泄漏原因包括 Native 层强引用、闭包捕获、全局缓存。AppFreeze 冻屏分析三步定位法确认故障类型与时间差 → 排查消息队列积压 → 分析主线程堆栈。常见场景包括 IPC 通信阻塞、等锁卡死、业务代码耗时/死循环。采样栈可识别锁竞争导致的频繁等锁故障模式。崩溃异常处理体系崩溃三类根因未捕获异常、Native 层错误、系统资源问题。四层兜底防御try-catch、Promise.catch、全局异常监听、Ability 生命周期异常处理。资源泄漏运行态检测HiDebug 资源采集 API 支持 FD、线程、Native 内存、GPU 内存、全局句柄五种资源类型。通过OH_HiDebug_StartProfiler/OH_HiDebug_StopProfiler采集资源分配栈。线上性能监控HiAppEvent 订阅 APP_FREEZE、APP_CRASH、RESOURCE_OVERLIMIT 事件。APMS 提供崩溃、冻屏、OOM、资源泄漏等多维度故障指标。FaultLogExtensionAbility 实现 30 分钟延迟通知处理应用未及时启动的故障补报场景。全链路治理闭环开发态检测 → 运行态监控 → 线上告警 → 修复验证。核心原则自动化、常态化在性能退化早期发现并修复问题。下节预告第8课将进入 ArkUI 的 AI 能力集成的学习涵盖端侧 AI 推理框架、AI 辅助代码生成、智能 UI 适配以及 AI 驱动的性能优化。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →