1# Subscribing to Resource Leak Events (ArkTS) 2 3<!--Kit: Performance Analysis Kit--> 4<!--Subsystem: HiviewDFX--> 5<!--Owner: @xuxinao--> 6<!--Designer: @peterhuangyu--> 7<!--Tester: @gcw_KuLfPSbe--> 8<!--Adviser: @foryourself--> 9 10## Available APIs 11 12This topic describes how to use the ArkTS APIs provided by HiAppEvent to subscribe to resource leak events. For details about how to use the APIs, see [@ohos.hiviewdfx.hiAppEvent (Application Event Logging)](../reference/apis-performance-analysis-kit/js-apis-hiviewdfx-hiappevent.md). 13 14 15### APIs for Setting Custom Parameters 16 17| API | Description | 18| ------------------------------------------------------------ | ------------------------------------------------------------ | 19| setEventParam(params: Record<string, ParamType>, domain: string, name?: string): Promise<void> | Sets custom parameters of an event. In resource leak events, only parameters of the JS memory leak event can be set.<br>Note: This API is supported since API version 20.| 20 21### Subscription APIs 22| API| Description| 23| -------- | -------- | 24| addWatcher(watcher: Watcher): AppEventPackageHolder | Adds a watcher to listen for application events.| 25| removeWatcher(watcher: Watcher): void | Removes a watcher to unsubscribe from application events. 26## How to Develop 27 28The following example describes how to subscribe to the memory leak event. 29 30### Step 1: Creating a Project 31 321. Create a project in DevEco Studio and select **Empty Ability**. In the **entry/src/main/ets/entryability/EntryAbility.ets** file, import the dependent modules. 33 34 ```ts 35 import { hiAppEvent, hilog, hidebug } from '@kit.PerformanceAnalysisKit'; 36 ``` 37 382. In the **entry/src/main/ets/entryability/EntryAbility.ets** file of the project, add a watcher in **onCreate()** to subscribe to system events. The sample code is as follows: 39 40 ```ts 41 // Assign a value to params, which is a key-value pair. 42 let params: Record<string, hiAppEvent.ParamType> = { 43 "test_data": 100, 44 }; 45 // Set custom parameters for the resource leak event. 46 hiAppEvent.setEventParam(params, hiAppEvent.domain.OS, hiAppEvent.event.RESOURCE_OVERLIMIT).then(() => { 47 hilog.info(0x0000, 'testTag', `HiAppEvent success to set event param`); 48 }).catch((err: BusinessError) => { 49 hilog.error(0x0000, 'testTag', `HiAppEvent code: ${err.code}, message: ${err.message}`); 50 }); 51 hiAppEvent.addWatcher({ 52 // Set the watcher name. The system identifies different watchers based on their names. 53 name: "watcher", 54 // Add the system events to watch, for example, the resource leak event. 55 appEventFilters: [ 56 { 57 domain: hiAppEvent.domain.OS, 58 names: [hiAppEvent.event.RESOURCE_OVERLIMIT] 59 } 60 ], 61 // Implement a callback for the registered system event so that you can apply custom processing to the event data obtained. 62 onReceive: (domain: string, appEventGroups: Array<hiAppEvent.AppEventGroup>) => { 63 hilog.info(0x0000, 'testTag', `HiAppEvent onReceive: domain=${domain}`); 64 for (const eventGroup of appEventGroups) { 65 // The event name uniquely identifies a system event. 66 hilog.info(0x0000, 'testTag', `HiAppEvent eventName=${eventGroup.name}`); 67 for (const eventInfo of eventGroup.appEventInfos) { 68 // Obtain the memory information when the resource leak event occurs. 69 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo=${JSON.stringify(eventInfo)}`); 70 } 71 } 72 } 73 }); 74 ``` 75 76### Step 2: Subscribing to Resource Leak Events 77 781. 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()**. 79 80 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 functionality.) 81 82 <!--RP1--> 83 For details about how to locate resource leak errors, see [Memory Leak Analysis](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-insight-session-snapshot). 84 <!--RP1End--> 85 86 The sample code is as follows: 87 88 ```ts 89 import { hidebug } from '@kit.PerformanceAnalysisKit'; 90 91 @Entry 92 @Component 93 struct Index { 94 @State leakedArray: string[][] = []; 95 96 build() { 97 Column() { 98 Row() { 99 Column() { 100 Button("pss leak") 101 .onClick(() => { 102 hidebug.setAppResourceLimit("pss_memory", 1024, true); 103 for (let i = 0; i < 20 * 1024; i++) { 104 this.leakedArray.push(new Array(1).fill("leak")); 105 } 106 }) 107 Button("js leak") 108 .onClick(() => { 109 for (let i = 0; i < 10000; i++) { 110 this.leakedArray.push(new Array(500000).fill(1)); 111 } 112 }) 113 } 114 } 115 .height('100%') 116 .width('100%') 117 } 118 } 119 } 120 ``` 121 1222. Click the **Run** button in DevEco Studio to run the project, click the **pss leak** button, and then a PSS memory leak event will be reported after 15 to 30 minutes. 123 For the same application, the resource 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. 124 1253. After a PSS memory leak event is reported, the system calls **onReceive()**. You can view the following event information in the **Log** window. 126 127 ```text 128 HiAppEvent onReceive: domain=OS 129 HiAppEvent eventName=RESOURCE_OVERLIMIT 130 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}} 131 ``` 132 133 As shown in the preceding information, **eventInfo** contains the [params](hiappevent-watcher-resourceleak-events.md#params) field of the resource leak event. You can determine the current leak type based on the **resource_type** field in **eventInfo**. 134 1354. Enable **System resource leak log** in **Developer options**. (You need to restart the device to enable or disable this functionality.) Click the **Run** button in DevEco Studio to run the project. Click **js leak** and wait for 3 to 5 seconds. The application will exit unexpectedly. After the application restarts, the system reports a JS memory leak event. 136 For the same application, the JS 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. 137 1385. After the JS memory leak event is reported, the system calls the **onReceive** function of the application. You can view the following event information in the **Log** window. 139 140 ```text 141 HiAppEvent onReceive: domain=OS 142 HiAppEvent eventName=RESOURCE_OVERLIMIT 143 HiAppEvent eventInfo={"domain":"OS","name":"RESOURCE_OVERLIMIT","eventType":1,"params":{"bundle_name":"com.example.myapplication","bundle_version":"1.0.0","external_log":[],"log_over_limit":true,"memory":{"limit_size":0,"live_object_size":0},"pid":14941,"resource_type":"js_heap","test_data":100,"time":1752564700511,"uid":20020181}} 144 ``` 145 146 In the preceding information, the **test_data** field in **eventInfo** is the content of the key-value pair set in step 1. 147 148### Step 3: Subscribing to js_heap Snapshots in the nolog Version 149 1501. In the nolog version, VM heap snapshot subscription is enabled for OOM scenarios caused by JS heap leaks. The application needs to call **hidebug.setAppResourceLimit** and **hiAppEvent.addWatcher** in sequence, and configure the following environment variables in the **AppScope/app.json5** file: 151 152 ```text 153 "appEnvironments": [ 154 { 155 "name": "DFX_RESOURCE_OVERLIMIT_OPTIONS", 156 "value": "oomdump:enable" 157 } 158 ] 159 ``` 160 161 **VM heap snapshot generation specifications of the nolog version** 162 163 The heap snapshot file size is about 0.4 GB to 1.2 GB (about 50 MB to 100 MB after being compressed into a .zip package). Due to the large size, the system controls the number of times that heap snapshots are generated. The specifications are as follows: 164 165 - Device: The JS heap snapshot file can be generated for five times a week. If this limit is exceeded, all applications cannot generate heap snapshots. 166 - Application: The JS heap snapshot file can be generated only once a week. 167 - If the remaining storage space of the device is less than 30 GB, **oomdump** is not triggered. 168 169 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. 170 171 > **NOTE** 172 > 173 > 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. 174 > 175 > 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. 176 > 177 > 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/ide-snapshot-basic-operations#section6760173514388). 178 > 179 > Since API 14, you can change the log file name extension to **.rawheap** and import it to DevEco Studio for display. For details, see [Importing Raw Heap Data Offline](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-snapshot-basic-operations#section1888195110017). 180