• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Subscribing to Resource Leak Events (ArkTS)
2
3## Available APIs
4
5For details about how to use the APIs (such as parameter usage constraints and value ranges), see [Application Event Logging](../reference/apis-performance-analysis-kit/js-apis-hiviewdfx-hiappevent.md).
6
7| API                                             | Description                                        |
8| --------------------------------------------------- | -------------------------------------------- |
9| addWatcher(watcher: Watcher): AppEventPackageHolder | Adds a watcher to listen for application events.|
10| removeWatcher(watcher: Watcher): void               | Removes a watcher to unsubscribe from application events.|
11
12## How to Develop
13
14The following describes how to subscribe to a memory leak event.
15
161. Create an ArkTS application project. In the **entry/src/main/ets/entryability/EntryAbility.ets** file, import the dependent modules.
17
18   ```ts
19   import { hiAppEvent, hilog, hidebug } from '@kit.PerformanceAnalysisKit';
20   ```
21
222. In the **entry/src/main/ets/entryability/EntryAbility.ets** file, add a watcher in **onCreate()** to subscribe to system events. The sample code is as follows:
23
24   ```ts
25    hiAppEvent.addWatcher({
26      // Set the watcher name. The system identifies different watchers based on their names.
27      name: "watcher",
28      // Add the system events to watch, for example, the resource leak event.
29      appEventFilters: [
30        {
31          domain: hiAppEvent.domain.OS,
32          names: [hiAppEvent.event.RESOURCE_OVERLIMIT]
33        }
34      ],
35      // Implement a callback for the registered system event so that you can apply custom processing to the event data obtained.
36      onReceive: (domain: string, appEventGroups: Array<hiAppEvent.AppEventGroup>) => {
37        hilog.info(0x0000, 'testTag', `HiAppEvent onReceive: domain=${domain}`);
38        for (const eventGroup of appEventGroups) {
39          // The event name uniquely identifies a system event.
40          hilog.info(0x0000, 'testTag', `HiAppEvent eventName=${eventGroup.name}`);
41          for (const eventInfo of eventGroup.appEventInfos) {
42            // You can obtain the memory information when the resource leak event occurs.
43            hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.memory=${JSON.stringify(eventInfo)}`);
44          }
45        }
46      }
47    });
48   ```
49
503. In the **entry/src/main/ets/pages/index.ets** file, add the **memoryleak** button and construct a scenario for triggering a resource leak event in **onClick()**.
51   In this case, use [hidebug.setAppResourceLimit](../reference/apis-performance-analysis-kit/js-apis-hidebug.md#hidebugsetappresourcelimit12) to set the memory limit to trigger a memory leak event, and enable **System resource leak log** in **Developer options**. (Restart the device to enable or disable this function.) The sample code is as follows:
52
53   ```ts
54    import hidebug from "@ohos.hidebug";
55
56    @Entry
57    @Component
58    struct Index {
59      @State leakedArray: string[][] = [];
60
61      build() {
62        Column() {
63          Row() {
64            Column() {
65              Button("pss leak")
66                .onClick(() => {
67                  hidebug.setAppResourceLimit("pss_memory", 1024, true);
68                  for (let i = 0; i < 20 * 1024; i++) {
69                    this.leakedArray.push(new Array(1).fill("leak"));
70                  }
71                })
72            }
73          }
74          .height('100%')
75          .width('100%')
76        }
77      }
78    }
79   ```
80
814. Click the **Run** button in DevEco Studio to run the project, and then a memory leak event will be reported after 15 to 30 minutes.
82   For the same application, the memory leak event can be reported at most once within 24 hours. If the memory leak needs to be reported again within a shorter time, restart the device.
83
845. After a memory leak event is reported, the system calls **onReceive()**. You can view the following event information in the **Log** window.
85
86   ```text
87   HiAppEvent onReceive: domain=OS
88   HiAppEvent eventName=RESOURCE_OVERLIMIT
89   HiAppEvent eventInfo={"domain":"OS","name":"RESOURCE_OVERLIMIT","eventType":1,"params":{"bundle_name":"com.example.myapplication","bundle_version":"1.0.0","memory":{"pss":2100257,"rss":1352644,"sys_avail_mem":250272,"sys_free_mem":60004,"sys_total_mem":1992340,"vss":2462936},"pid":20731,"resource_type":"pss_memory","time":1502348798106,"uid":20010044,"external_log": ["/data/storage/el2/log/resourcelimit/RESOURCE_OVERLIMIT_1725614572401_6808.log", "/data/storage/el2/log/resourcelimit/RESOURCE_OVERLIMIT_1725614572412_6808.log"], "log_over_limit": false}}
90   ```
91
926. Currently, in the nolog version<!--Del--> of the commercial OS based on OpenHarmony<!--Del-->, the function of subscribing to VM heap snapshots is enabled. The application needs to call **hidebug.setAppResourceLimit** and **hiAppEvent.addWatcher** in sequence, and configure the following environment variables in the **AppScope/app.json5** file:
93
94    ```text
95    "appEnvironments": [
96      {
97        "name": "DFX_RESOURCE_OVERLIMIT_OPTIONS",
98        "value": "oomdump:enable"
99      }
100    ]
101    ```
102
103    The size of a heap snapshot file ranges from 0.4 GB to 1.2 GB (about 50 MB to 100 MB after being compressed in ZIP format). Therefore, the system limits the number of times that heap snapshots are generated. The specifications are as follows:
104      - Device: The OOM heap snapshot file can be generated for five times a week. If this limit is exceeded, all applications cannot generate heap snapshots.
105      - Application: The OOM heap snapshot file can be generated only once a week.
106      - If the remaining storage space of the device is less than 30 GB, **oomdump** is not triggered.
107    During debugging, you can adjust the system time to seven days later and restart the device to reset the number of times that the application triggers **oomdump**, so that you can quickly complete function adaptation and verification.
108
109    > **NOTE**
110    >
111    > After receiving the subscribed event, the application should obtain the path of the heap snapshot file from the **external_log** field of the event, move or upload the file to the cloud as soon as possible, and then delete the original heap snapshot file. Otherwise, the next heap snapshot file may fail to be generated due to insufficient storage space (up to 2 GB) of the application sandbox path directory.<br>
112    > The value **field** in the JSON5 configuration file supports the key-value pair set **key1:value1;key2:value2;...**. Currently, the **oomdump** function can be enabled in the nolog version only for applications configured with the preceding key-value pairs.<br>
113    > Change the extension of the .log file generated after subscription to **.rawheap**, use [rawheap-translator](../tools/rawheap-translator.md) to convert the file to a .heapsnapshot file, and open the file using DevEco Studio or a browser. For details, see [Importing Heap Snapshots Offline](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-snapshot-basic-operations-V5#section6760173514388).
114