写点什么

JSLeakWatcher 特性指导

  • 2026-06-29
    北京
  • 本文字数:2668 字

    阅读完需:约 9 分钟

请在文章开头添加(文案部分):

本原创文章帖发布在华为开发者联盟社区,欢迎开发者前往访问评论交流,更多与该内容相关讨论,请点击原帖查看:

JSLeakWatcher特性指导-华为开发者话题 | 华为开发者联盟

概述

背景

在 ArkTS 开发中,若一个 ArkTS 对象不再需要,但仍被某个引用链“意外”持有,则垃圾回收器无法回收该内存,从而导致内存泄漏。

ArkTS 对象内存泄漏,通常会带来以下影响:

1、性能:若应用占用内存持续增长,系统为释放内存会频繁触发 GC,而 GC 执行时会暂停应用主线程(Stop-The-World 机制),导致界面卡顿、滑动不流畅;长期泄漏同时也会让内存碎片化严重,系统分配/释放内存效率降低,进一步拖慢应用运行速度,发生响应变慢等问题;

2、内存:若应用泄漏内存持续积累并达到 ArkTS Local 堆/共享堆或进程的 OOM 的上限阈值时,则会产生 JS Crash;

3、功耗:系统频繁 GC 会消耗大量 CPU 资源,持续高占用会导致设备发热,加速电量消耗;

4、功能:部分泄漏会因对象引用残留间接导致功能异常(如 ArkUI 组件状态错乱、资源冲突、回调重复执行等)。

JSLeakWatcher 介绍

为帮助开发人员快速定位 ArkTS 对象内存泄漏问题,HarmonyOS 提供了 ArkTS 内存泄漏检测能力 JSLeakWatcher,开发者可轻松接入相关 API,实现对系统内具有生命周期的 ArkTS 组件对象定期执行泄漏自检测。

当检测到 ArkTS 对象有内存泄漏时,JSLeakWatcher 会生成泄漏信息文件(包括*.rawheap 文件和*.jsleaklist 文件,详细参考 2.4),将这两个文件导入 IDE(DevEco Studio 6.0.0 起均支持),就可以获取泄露对象列表。通过泄漏对象列表中的泄漏对象直接跳转到引用链,加速找到持有该泄漏对象的根 GC_ROOT,提升泄漏问题闭环效率,降低定界定位成本。对于自定义组件和 Ability 组件对象,JSLeakWatcher 可以直接关联到业务代码信息,XComponent 组件、NodeContainer 组件、Window 组件不支持关联到业务代码信息。

实现原理

原理描述

JSLeakWatcher 提供了清晰、易用的 ArkTS 接口,主要功能如下:

1、定期对目标应用执行一次垃圾回收操作(FullGC),尝试回收当前所有根不可达的 ArkTS 对象(未被 GC_ROOT 对象持有的 ArkTS 对象);

2、当执行完垃圾回收操作后,若框架检测到仍有未被回收的 ArkTS 对象,则立即生成此刻的 ArkTS 堆快照(*.rawheap)文件及泄漏对象列表(*.jsleaklist)文件,并存放在应用沙箱内。ArkTS 对象发生内存泄漏,通常是因为对象在生命周期结束后仍未被解除引用,导致垃圾回收器(GC)无法识别并将其回收。常见原因包括:

(1)Native 层强引用该对象:在 Node-API 中对 ArkTS 对象创建了持久化强引用。(Node-API 介绍参考 Node-API 简介;创建和销毁强引用方式参考 napi_create_reference、napi_delete_reference);

(2)闭包捕获:内部函数持有对外部作用域 ArkTS 对象的引用,即使外部作用域已退出;

(3)全局或模块级缓存:使用 Map、Array 缓存长期持有 ArkTS 对象。

泄漏检测流程

1、应用在启动后调用 enableLeakWatcher()接口开启 ArkTS 泄漏检测功能。 2、检测流程:

(1)通过 FinalizationRegistry 机制,注册监控组件对象的 GC 回调函数,同时注册销毁回调函数。说明:FinalizationRegistry 是 JavaScript 提供的弱引用监听机制,当注册的对象被垃圾回收时,会自动触发预设的回调函数;

(2)当组件对象被销毁时,销毁的回调函数会将对象记录在 list1 中,这些被销毁,同时记录在 list1 中的对象应该在 GC 后被清除掉;

(3)被销毁的组件在被 GC 时(周期性执行,默认 90 秒),GC 的回调函数会将该对象记录在 list2 中,记录在 list2 中的对象被成功 GC 掉;

(4)list1-list2 就是泄漏对象;

(5)list1-list2 如果不为空,则说明存在泄漏:GC 后延迟一段时间(默认 5 秒),异步 dump ArkTS 堆快照生成*.rawheap 文件,然后根据 list1-list2 对象数组,生成*.jsleaklist 文件,最后将*.rawheap 文件和*.jsleaklist 文件落盘在应用沙箱中;

(6)通过将*.rawheap 文件和*.jsleaklist 文件导出到 IDE 中,即可以获取泄漏对象的详细信息。

3、应用在退出时调用 enableLeakWatcher 接口关闭 ArkTS 泄漏检测功能。

关键能力

截止 7.0 版本(API 26.0.0),JSLeakWatcher 支持以下关键能力(含配置):

1、组件相关

(1)支持监控五大类型组件,包括:NodeContainer、Ability、Window、XComponent、CustomComponent;

(2)支持指定要检测的对象变量名,只监控相关对象是否存在泄漏;

(3)支持指定要检测的组件类型名,只监控相关类型下面所有的对象是否存在泄漏;

(4)支持指定要检测的自定义组件 id 名单,只监控相关 id 的对象是否存在泄漏;

(5)支持指定不检测的自定义组件类名、Abilty 类名和 Window 窗口名名单,传入自定义组件类名、Abilty 类名和 Window 窗口名名单,不监控相关对象是否存在泄漏;

2、调用机制

(1)插桩调用:支持在业务代码中调用接口使用;

(2)测试环境新增支持应用免插桩调用(通过将系统参数“hiviewdfx.hichecker.jsleakwatcher.leak.check”设置为“enable.应用名”),相关配置使用默认值,发生泄漏后,上报系统事件,最后在 Deveco Testing(从 7.0.0.200 版本开始支持)呈现泄漏内容。

3、dump 机制

(1)支持异步 dump 快照;

(2)支持自定义配置 dump 触发条件(应用在前台/后台泄漏个数为多少时执行 dump);

(3)支持配置最大 dump 个数,默认 10 份快照文件,超过后会老化;

(3)支持配置 GC 后多久执行快照 dump,默认是 5 秒。

4、快照生成和老化机制

(1)只要有泄漏被检测到,就会新 dump 一份快照并生成一个泄漏列表文件(新文件生成之前,同一生命周期内生成的老的快照文件和泄漏列表文件都会被删除)。文件生成完之后,会通过回调告知应用快照文件路径和泄露列表文件路径;

(2)应用沙箱内文件上限默认是 20 个,超过 20 个文件会被老化。

5、检测间隔

(1)支持配置每轮检测间隔时间,默认且最小为 90 秒。如果用户设置的时间小于 90 秒,将不会生效。注意,GC 属于高开销操作,会导致应用卡顿,因此建议开发者根据实际情况调大检测间隔,减轻卡顿频率。

生成文件介绍

1、*.rawheap 文件 记录了抓快照时所有无法被回收的 ArkTS 对象信息,包括泄漏对象和 GC_ROOT 可达对象。快照内容包括 ArkTS 对象的节点属性与引用链,包括对象类型、涉及的代码行等。

2、*.jsleaklist 文件 统计无法回收的 ArkTS 泄漏对象列表,导入到 IDE 可以和 rawheap 中的 ArkTS 对象通过 ID 进行匹配,查看 ArkTS 对象中的各属性。

开发实践

见官方文档:

https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-js-leak-watcher

4、接口说明

见官方文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-jsleakwatcher