本文同步发表于 微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

   资源泄漏是指句柄、线程或内存等系统资源在应用运行后未正确释放,导致被长期占用。若耗尽,可能引发系统卡死或重启。

系统通过周期性采样进行监控,一旦资源使用超过预设阈值,便会抓取详细维测日志并上报泄漏事件。开发中可通过订阅 HiAppEvent 事件或使用分析工具获取这些日志。

主要泄漏类型的检测逻辑与触发条件,如图:

二、分析方法

1. 句柄泄漏
  • 触发:进程文件描述符总数 > 5000。

  • 日志文件[pid]_fd_leak.txt

  • 关键信息

    • Top 10 泄漏类型:统计最常泄漏的句柄类型(如 ashmemsocket

    • 特殊类型详情:若 ashmemsocketpipesync_filedmabuf 这五类句柄任一超过1000个,会记录整机详细分配信息,有助于定位共享内存、网络连接、GPU缓冲等泄漏

    • 调用栈:泄漏判定后,会Hook相关系统调用10分钟,记录并聚类调用栈,是定位代码根源的关键

  • 分析命令:调用栈需使用 addr2line 等工具结合符号表解析

2. 线程泄漏
  • 触发:进程总线程数 > 700

  • 日志文件[pid]_thread_leak.txt

  • 关键信息

    • Top 10 线程名:泄漏最多的线程名称(未命名线程会显示进程名)

    • 线程启动时间:通过 start_time(jiffies) 可推测线程创建时间点

    • 线程快照:泄漏时所有线程的调用栈,可查看线程阻塞位置(如等待锁、条件变量)

3. JS内存泄漏
  • 触发:ArkTS虚拟机堆内存使用率 > 85% 或发生OOM

  • 日志文件memleak-js-[process_name]-[pid]-[tid]-[timestamp].rawheap

  • 分析方法:此文件为二进制内存快照,需使用 translator工具 转换为 .heapsnapshot 文件,随后可导入 DevEco Studio 或 Chrome DevTools 的 Memory 面板进行分析,查看对象保留路径

4. Native内存泄漏
  • 触发:进程的动态内存峰值持续超过其基线值的2倍(基线为应用历史平均峰值)

  • 日志文件:包含采样、维测、调用栈三部分:

    • 采样 (-sample.txt):表格记录内存指标随时间变化,可直观观察增长趋势。关键指标包括 PSS(按比例分摊的物理内存)、RSS(实际驻留内存)、TotalMem(总内存使用)

    • 维测 (-smaps.txt):包含进程详细的内存映射 (smaps) 和内存分配器 (jemalloc) 快照,用于分析内存区域和分配统计

    • 调用栈 (-[timestamp].txt):记录15分钟内内存分配的调用栈,是定位泄漏代码的核心。需将文件后缀改为 .nas 后,用 DevEco Studio Profiler 的 Allocation 视图打开分析。在“Call Trees”中筛选 “Created & Existing”,按内存未释放量排序,优先排查占比高的堆栈

5. 内核内存泄漏 (ashmem/ion/gpu)
  • 触发:内核管理的共享内存、ION缓冲区、GPU显存等超过系统基线

  • 日志文件memleak-kernel-[module]-0-*.txt

  • 关键信息:日志会详细列出整机范围内所有持有该类型内存的进程、句柄、大小、申请者等信息。例如,ion 泄漏会列出每个 dmabuf 缓冲区的详细信息,帮助定位是哪个进程的哪个组件(如媒体播放、图形处理)未释放缓冲

三、日志获取的三种方式

方式 工具/接口 适用场景与说明
方式一 DevEco Testing (探索测试) 推荐。自动收集设备日志 (/data/log/reliability/resource_leak/),并按进程、故障类型、时间分类展示,最便捷。
方式二 DevEco Studio Profiler 主动分析。用于开发阶段主动 profiling,支持实时捕获 Native 调用栈 (Allocation) 和 JS 堆快照 (Snapshot)。
方式三 HiAppEvent 接口订阅 线上监控。通过代码订阅资源泄漏事件,可用于应用自监控或自动化测试框架。日志存储在 /data/storage/el2/log/resourcelimit/

四、说明

  1. 版本差异:在 nolog版本(通常为商用发布版本)上,句柄调用栈、Native调用栈、JS内存快照等详细维测默认关闭以保障性能和隐私。若需在nolog版获取JS快照,需特殊订阅。

  2. 自定义阈值:开发阶段可使用 hidebug.setAppResourceLimit API 为当前应用设置自定义的泄漏判定阈值(如更低的句柄数),便于早期发现问题。此接口严禁在正式发布版本中使用。

  3. 开启抓栈:在nolog版本设备上,若需获取句柄泄漏的调用栈,需在开发者选项中手动打开 “系统资源泄漏日志” 开关并重启设备。

  4. 分析流程

    • 先看头部和概览:确认泄漏类型、进程、泄漏数量。

    • 再看Top列表:快速定位最严重的泄漏点(如哪种句柄、哪个线程最多)。

    • 最后深挖详情与调用栈:结合特殊类型详细信息和调用栈,精确定位到代码行。

  5. 虚拟机内存计算:JS内存使用率 = heapUsed / totalHeap。这两个值可通过 hidebug.getAppVMMemoryInfo() API 获取。

五、总结

HarmonyOS的资源泄漏检测机制提供了一个从自动检测、阈值判定、详细日志抓取到多维分析的完整闭环。核心价值在于:

  • 线上监控:通过订阅 HiAppEvent,可以及时发现线上用户设备的潜在泄漏风险

  • 线下调试:利用 DevEco Testing 和 Profiler,结合详细的调用栈和内存快照,可以高效地复现和根因定位泄漏问题

  • 性能优化:通过分析内存采样趋势和分配细节,优化应用内存使用模式

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐