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![image](./figures/gc-heap-space.png)
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![image](./figures/gc-process.png)
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![image](./figures/gc-shared-heap.png)
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![image](./figures/gc-smart-feature.png)
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