1# GC 2 3Garbage Collection (GC) is the process of finding garbage in memory and releasing and reclaiming memory space. Two GC algorithms are mainly used: reference counting and tracing GC. Based on the generational model (young generation and old generation), ArkTS uses both the reference counting and object tracking algorithms to concurrently execute GC tasks, achieving high-performance memory reclamation in different scenarios. 4 5In ArkTS, data types are classified into simple type and reference type. Data of the simple type is stored in stacks, and its space is automatically allocated and reclaimed by the operating system. Data of the reference type is stored in heaps, and its space must be manually reclaimed by the engine. GC is a management mechanism for automatically reclaiming heap space. 6 7## Heap Space Structure and Parameters 8 9### Heap Space Structure 10 11 12 13- Semi Space: stores young generation, that is, newly created objects, which may be short-lived. The copying algorithm is used to reclaim memory. 14- Old Space: stores old generation, that is, long-surviving objects. Multiple algorithms are used to reclaim memory based on scenarios. 15- Huge Object Space: stores huge objects. A separate region is used to store a huge object. 16- Read Only Space: stores read-only data at runtime. 17- Non-Movable Space: stores unmovable objects. 18- Snapshot Space: stores heap snapshots. 19- Machine Code Space: stores machine codes. 20 21Each space is divided into one or more regions for refined management. A region is the unit applied for from the memory allocator. 22 23### Parameters 24 25> **NOTE** 26> 27> Among all the parameters described in this section, if no description is provided for how to configure a parameter, then the parameter is automatically set by the system. 28 29For some of the parameters, three values or value ranges are provided, corresponding to the three value ranges of the total heap size: 64–128 MB/128–256 MB/ > 256 MB. If the remaining memory space is sufficient, the third value range (> 256 MB) is used by default. 30 31#### Parameters of Semi Space 32 33Two Semi Spaces are generated in the heap for the copying algorithm to use. 34 35| Parameter| Value or Value Range| Description| 36| --- | --- | :--- | 37| semiSpaceSize | 2–4 MB/2–8 MB/2–16 MB| Size of Semi Space. The value varies according to the total heap size.| 38| semiSpaceTriggerConcurrentMark | 1 M/1.5 M/1.5 M| Threshold for independently triggering the concurrent marking phase of Semi Space for the first time.| 39| semiSpaceStepOvershootSize| 2 MB | Maximum overshoot size of Semi Space.| 40 41#### Parameters of Other Spaces 42 43| Parameter| Value or Value Range| Description| 44| --- | --- | :--- | 45| defaultReadOnlySpaceSize | 256 KB | Default size of Read Only Space.| 46| defaultNonMovableSpaceSize | 2 MB/6 MB/64 MB | Default size of Non-Movable Space.| 47| defaultSnapshotSpaceSize | 512 KB/512 KB/ 4 MB | Default size of Snapshot Space.| 48| defaultMachineCodeSpaceSize | 2 MB/2 MB/8 MB | Default size of Machine Code Space.| 49 50#### Parameters of Old Space and Huge Object Space 51 52During initialization, the parameter is set to the size of the unallocated heap space left. 53 54| Parameter| Value or Value Range| Description| 55| --- | --- | :--- | 56| oldSpaceOvershootSize | 4 MB/8 MB/8 MB | Maximum overshoot size of Old Space.| 57 58#### Heap Size Parameters 59 60| Parameter| Value or Value Range| Description| 61| --- | --- | :--- | 62| HeapSize | 448–1024 MB | Total heap size. The actual size allocated varies according to the heap type. The lower limit is reduced in the case of an insufficient memory pool.| 63| SemispaceSize | 2–4 MB/2–8 MB/2–16 MB| Size of Semi Space.| 64| NonmovableSpaceSize | 2 MB/6 MB/64 MB | Size of Non-Movable Space.| 65| SnapshotSpaceSize | 512 KB| Size of Snapshot Space.| 66| MachineCodeSpaceSize | 2 MB| Size of Machine Code Space.| 67 68#### Maximum Number of Worker Thread Heaps 69 70| Parameter| Value or Value Range| Description| 71| --- | --- | --- | 72| heapSize | 768 MB | Size of the heap space of the work type.| 73 74#### Size of the Interpreter Stack 75 76| Parameter| Value or Value Range| Description| 77| --- | --- | --- | 78| maxStackSize | 128 KB| Maximum frame size of the interpreter stack.| 79 80#### Concurrency Parameters 81 82| Parameter| Value| Description| 83| --- | ---: | --- | 84| gcThreadNum | 7 | Number of GC threads. The default value is 7. You can set this parameter using **gc-thread-num**.| 85| MIN_TASKPOOL_THREAD_NUM | 3 | Minimum number of threads in the thread pool.| 86| MAX_TASKPOOL_THREAD_NUM | 7 | Maximum number of threads in the thread pool.| 87 88Note: The thread pool is used to execute concurrent tasks in the GC process. During thread pool initialization, all the three parameters need to be considered. If **gcThreadNum** is a negative value, the number of threads in the initialized thread pool is the number of CPU cores divided by 2. 89 90#### Other Parameters 91 92| Parameter| Value| Description| 93| --- | --- | --- | 94| minAllocLimitGrowingStep | 2 M/4 M/8 M| Minimum increase step of **oldSpace**, **heapObject**, and **globalNative** when the heap space size is recalculated.| 95| minGrowingStep | 4 M/8 M/16 M | Minimum increase step of **oldSpace**.| 96| longPauseTime | 40 ms| Threshold for checking for a long GC pause. In the case of long GC pauses, complete GC log is printed, facilitating fault locating and analysis. You can set this parameter using **gc-long-paused-time**.| 97 98### Other: The maximum native memory of the ArrayBuffer in a single VM is 4 GB. 99 100## GC Process 101 102 103 104 105### HPP GC 106 107High Performance Partial Garbage Collection (HPP GC) achieves efficient garbage collection by employing generational models, hybrid algorithms, and GC process optimization. 108 109#### Young GC 110 111- **When to trigger**: The young GC trigger threshold ranges from 2 MB to 16 MB, depending on the allocation speed and survival rate. 112- **Description**: Reclaims the young-generation objects newly allocated to Semi Space. 113- **Scenario**: Foreground 114- **Log keywords**: [ HPP YoungGC ] 115 116#### Old GC 117 118- **When to trigger**: The old GC trigger threshold ranges from 20 MB to 300 MB. In most cases, the threshold of the first old GC is about 20 MB, and the threshold for subsequent old GC operations is adjusted based on the survival rate and memory usage. 119- **Description**: Sorts and compresses the space of the young generation and some space of the old generation, and sweeps other spaces. The trigger frequency is much lower than that of the young GC. Due to full marking, a single old GC operation takes about 5 ms to 10 ms, longer than that of the young GC. 120- **Scenario**: Foreground 121- **Log keywords**: [ HPP OldGC ] 122 123#### Full GC 124 125- **When to trigger**: Full GC is not triggered based on the memory threshold. After the application is switched to the background, full GC is triggered if the size of the object that can be reclaimed is expected to be greater than 2 MB. You can also trigger full GC using the DumpHeapSnapshot and AllocationTracker tools or calling native interfaces and JS/TS interfaces. 126- **Description**: Performs full compression on the young generation and old generation. Full GC is mainly used in performance-insensitive scenarios to reclaim memory space to the maximum extent. 127- **Scenario**: Background 128- **Log keywords**: [CompressGC] 129 130Smart GC or idle GC is based on these three GC modes. 131 132### Trigger Policy 133 134#### GC Triggered by Space Thread 135 136- Functions: **AllocateYoungOrHugeObject**, **AllocateHugeObject**, and other allocation-related functions 137- Restriction parameters: corresponding space thresholds 138- Description: GC is triggered when the space applied for by an object reaches the corresponding threshold. 139- Log keywords: **GCReason::ALLOCATION_LIMIT** 140 141#### GC Triggered by Native Binding Size 142 143- Functions: **GlobalNativeSizeLargerThanLimit** 144- Restriction parameters: **globalSpaceNativeLimit** 145- Description: It affects the decision for performing full marking and concurrent marking. 146 147#### GC Triggered Upon Switching to Background 148 149- Functions: **ChangeGCParams** 150- Description: Full GC is triggered when the application switches to the background. 151- Log keywords: **app is inBackground**, **app is not inBackground**, and 152 **GCReason::SWITCH_BACKGROUND** 153 154### Execution Policy 155 156#### Concurrent Marking 157 158- Function: **TryTriggerConcurrentMarking** 159- Description: Attempts to trigger concurrent marking and hand over the object traversal task to the thread pool to reduce the time that the main thread is being suspended. 160- Log keywords: **fullMarkRequested, trigger full mark**, **Trigger the first full mark**, **Trigger full mark**, **Trigger the first semi mark**, and **Trigger semi mark** 161 162#### Threshold Adjustment Before and After GC of Semi Space 163 164- Function: **AdjustCapacity** 165- Description: Adjusts the GC trigger threshold of Semi Space after GC to optimize the space structure. 166- Log keywords: There is no direct log. The GC statistics logs show that the young space threshold before GC is dynamically adjusted. 167 168#### Threshold Adjustment After the First Old GC 169 170- Function: **AdjustOldSpaceLimit** 171- Description: Adjusts the old space threshold based on the minimum increase step and average survival rate. 172- Log keywords: **"AdjustOldSpaceLimit oldSpaceAllocLimit_: "<< oldSpaceAllocLimit <<" globalSpaceAllocLimit_: " << globalSpaceAllocLimit_;** 173 174#### Old Space/Global Space Threshold and Increase Factor for the Second and Later Old GC Operations 175 176- Function: **RecomputeLimits** 177- Description: Recalculates and adjusts **newOldSpaceLimit**, **newGlobalSpaceLimit**, **globalSpaceNativeLimit**, and the increase factor based on the current GC statistics. 178- Log keywords: **"RecomputeLimits oldSpaceAllocLimit_: "<< newOldSpaceLimit_ <<" globalSpaceAllocLimit_: "<< globalSpaceAllocLimit_ <<" globalSpaceNativeLimit_: "<< globalSpaceNativeLimit_;** 179 180#### CSet for Partial GC 181 182- Function: **OldSpace::SelectCSet ()** 183- Description: Selects a region with a small number of living objects and a low reclamation cost for partial GC. 184- Log keywords: **Select CSet failure: number is too few**, 185 **"Max evacuation size is 6_MB. The CSet region number: " << selectedRegionNumber;**, 186 and **"Select CSet success: number is " << collectRegionSet_.size();** 187 188## SharedHeap 189 190### Shared Heap Structure 191 192 193 194- Shared Old Space: stores common shared objects. The young generation and old generation are not distinguished in the shared heap. 195- Shared Huge Object Space: stores huge shared objects. A separate region is used to store a huge object. 196- Shared Read Only Space: stores read-only shared data at runtime. 197- Shared Non-Movable Space: stores unmovable shared objects. 198 199Note: The shared heap is mainly used to share objects between threads. It improves efficiency and reduces memory usage. The shared heap does not belong to a specific thread. It stores objects with shared value and has a higher survival rate. It does not evolve Semi Space. 200 201## Technical Features 202 203### Smart GC 204 205#### Description 206 207In performance-sensitive scenarios, the GC trigger threshold of the JS thread is temporarily adjusted to the maximum JS heap size (448 MB by default) to prevent frame loss caused by the GC trigger. (Smart GC does not take effect for the Worker thread and TaskPool thread.) However, if the performance-sensitive scenario lasts for a long period of time and the allocated objects reach the maximum heap size, GC is triggered. This GC takes a long time because too many objects are accumulated. 208 209#### Performance-Sensitive Scenarios 210 211- Application cold start 212- Application sliding 213- Page redirection upon click 214- Jumbo frame 215 216Currently, this feature is controlled by the system. Third-party apps do not have APIs to directly call this feature. 217 218Log keyword: **SmartGC** 219 220#### Interaction Process 221 222 223 224Mark performance-sensitive scenarios. When entering or exiting a performance-sensitive scenario, mark the scenario on the heap to avoid unnecessary GC and maintain high performance. 225 226## Log Description 227 228### Typical Logs 229 230``` 231// Actual size occupied by the object before GC (actual size occupied by the region) - > Actual size occupied by the object after GC (actual size occupied by the region), total duration (+concurrentMark duration), and GC triggering cause 232C03F00/ArkCompiler: [gc] [ CompressGC ] 26.1164 (35) -> 7.10049 (10.5) MB, 160.626(+0)ms, Switch to background 233// GC statuses and application name 234C03F00/ArkCompiler: [gc] IsInBackground: 1; SensitiveStatus: 0; OnStartupEvent: 0; BundleName: com.huawei.hmos.filemanager; 235// Time consumption statistics of each GC phase 236C03F00/ArkCompiler: [gc] /***************** GC Duration statistic: ****************/ 237C03F00/ArkCompiler: [gc] TotalGC: 160.626 ms 238C03F00/ArkCompiler: Initialize: 0.179 ms 239C03F00/ArkCompiler: Mark: 159.204 ms 240C03F00/ArkCompiler: MarkRoots: 6.925 ms 241C03F00/ArkCompiler: ProcessMarkStack: 158.99 ms 242C03F00/ArkCompiler: Sweep: 0.957 ms 243C03F00/ArkCompiler: Finish: 0.277 ms 244// Memory size occupied by each part after GC 245C03F00/ArkCompiler: [gc] /****************** GC Memory statistic: *****************/ 246C03F00/ArkCompiler: [gc] AllSpaces used: 7270.9KB committed: 10752KB 247C03F00/ArkCompiler: ActiveSemiSpace used: 0KB committed: 256KB 248C03F00/ArkCompiler: OldSpace used: 4966.9KB committed: 5888KB 249C03F00/ArkCompiler: HugeObjectSpace used: 2304KB committed: 2304KB 250C03F00/ArkCompiler: NonMovableSpace used: 0KB committed: 2304KB 251C03F00/ArkCompiler: MachineCodeSpace used: 0KB committed: 0KB 252C03F00/ArkCompiler: HugeMachineCodeSpace used: 0KB committed: 0KB 253C03F00/ArkCompiler: SnapshotSpace used: 0KB committed: 0KB 254C03F00/ArkCompiler: AppSpawnSpace used: 4736.34KB committed: 4864KB 255C03F00/ArkCompiler: [gc] Anno memory usage size: 45 MB 256C03F00/ArkCompiler: Native memory usage size:2.99652 MB 257C03F00/ArkCompiler: NativeBindingSize: 0.577148KB 258C03F00/ArkCompiler: ArrayBufferNativeSize: 0.0117188KB 259C03F00/ArkCompiler: RegExpByteCodeNativeSize:0.280273KB 260C03F00/ArkCompiler: ChunkNativeSize: 19096 KB 261C03F00/ArkCompiler: [gc] Heap alive rate: 0.202871 262// Overall statistics of this type of GC on the VM 263C03F00/ArkCompiler: [gc] /***************** GC summary statistic: *****************/ 264C03F00/ArkCompiler: [gc] CompressGC occurs count 6 265C03F00/ArkCompiler: CompressGC max pause: 2672.33 ms 266C03F00/ArkCompiler: CompressGC min pause: 160.626 ms 267C03F00/ArkCompiler: CompressGC average pause:1076.06 ms 268C03F00/ArkCompiler: Heap average alive rate: 0.635325 269``` 270 271- GC type, which can be [HPP YoungGC], [HPP OldGC], [CompressGC] and [SharedGC]. 272- **TotalGC**: total duration. The following lists the time required for each phase, including Initialize, Mark, MarkRoots, ProcessMarkStack, Sweep, and Finish. The actual phase varies according to the GC process. 273- **IsInBackground**: specifies whether it is a background scenario. The options are **1** (background scenario) and **0** (non-background scenario). 274- **SensitiveStatus**: specifies whether it is a sensitive scenario. The options are **1** (sensitive scenario) and **0** (non-sensitive scenario). 275- **OnStartupEvent**: specifies whether it is a cold start scenario. The options are **1** (cold start scenario) and **0** (non-cold start scenario). 276- **used**: actual memory space occupied by the allocated object. 277- **committed**: size of the memory allocated to the heap. Memory space is allocated by region, and a region is not fully occupied by objects. Therefore, if **committed** is greater than or equal to **used**, the values of **HugeObjectSpace** is the same under **used** and **committed** because one object occupies the region. 278- **Anno memory usage size**: memory size applied by all heaps of the current process, including the heap and shared heap. 279- **Native memory usage size**: native memory size requested by the current process. 280- **NativeBindingSize**: size of the native memory bound to the objects in the heap of the current process. 281- **ArrayBufferNativeSize**: native memory size of the array cache requested by the current process. 282- **RegExpByteCodeNativeSize**: native memory size of the regular expression bytecode requested by the current process. 283- **ChunkNativeSize**: chunk native memory size requested by the current process. 284- **Heap alive rate**: survival rate of objects in the heap. 285 286## GC Developer Debugging Interfaces 287 288> **NOTE** 289> The following interfaces are used only for debugging. They are informal external SDK interfaces and should not be used in official application versions. 290 291### ArkTools.hintGC() 292 293- Call method: **ArkTools.hintGC()** 294- Type: JS interface 295- Description: Determines whether full GC is required. In the background scenario or if the expected survival rate is lower than the preset value, full GC is triggered. In performance-sensitive scenarios, full GC is not triggered. 296- Use scenario: The developer asks the system to perform GC. 297- Log keywords: There is no direct log. Only external trigger (**GCReason::TRIGGER_BY_JS**) can be found. 298 299 300Example: 301 302``` 303// Declare the interface first. 304declare class ArkTools { 305 static hintGC(): void; 306} 307 308@Entry 309@Component 310struct Index { 311 @State message: string = 'Hello World'; 312 build() { 313 Row() { 314 Column() { 315 Text(this.message) 316 .fontSize(50) 317 .fontWeight(FontWeight.Bold) 318 Button("Trigger Hint GC").onClick((event: ClickEvent) => { 319 ArkTools.hintGC(); // Directly called in a method. 320 }) 321 } 322 .width('100%') 323 } 324 .height('100%') 325} 326} 327``` 328