Skip to content

Commit 31d4333

Browse files
author
alfredo-toledano
committed
doc(docs.topics.native.memoryManager): add notes
1 parent 93c5aae commit 31d4333

File tree

1 file changed

+74
-68
lines changed

1 file changed

+74
-68
lines changed

docs/topics/native/native-memory-manager.md

Lines changed: 74 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,105 @@
11
[//]: # (title: Kotlin/Native memory management)
22

3-
Kotlin/Native uses a modern memory manager that is similar to the JVM, Go, and other mainstream technologies, including
4-
the following features:
53

6-
* Objects are stored in a shared heap and can be accessed from any thread.
7-
* Tracing garbage collection (GC) is performed periodically to collect objects that are not reachable from the "roots",
8-
like local and global variables.
4+
* Kotlin/Native's memory manager
5+
* == Java, Go or Swift's memory manager
6+
* 👀features👀
7+
* Objects
8+
* are stored | shared heap
9+
* -- can be accessed from -- ANY thread
10+
* Tracing garbage collection (GC) -- is performed -- periodically collecting objects / NOT reachable from the "roots" (_Example:_
11+
like local and global variables)
912

1013
## Garbage collector
1114

12-
Kotlin/Native's GC algorithm is constantly evolving. Currently, it functions as a stop-the-world mark and concurrent sweep
13-
collector that does not separate the heap into generations.
15+
* Kotlin/Native's GC algorithm is constantly evolving
16+
* stop-the-world mark + concurrent sweep collector / heap is NOT separated into generations ❓
17+
* stop-the-world mark == full parallel mark / combines paused mutators + GC thread + optional marker threads
18+
* | marking process, by default, paused mutators + >=1 GC thread
19+
* if you want to disable the full parallel mark -> pass `-Xbinary=gcMarkSingleThreaded=true` compilation option
20+
* may increase -- the -- pause time of the garbage collector
21+
* GC thread
22+
* == GC is
23+
* executed | separate thread
24+
* started -- based on the -- timer & memory pressure heuristics
1425

15-
The GC uses a full parallel mark that combines paused mutators, the GC thread, and optional marker threads to process
16-
the mark queue. By default, paused mutators and at least one GC thread participate in the marking process.
17-
You can disable the full parallel mark with the `-Xbinary=gcMarkSingleThreaded=true` compilation option.
18-
However, this may increase the pause time of the garbage collector.
26+
* once the marking phase is completed ->
27+
* GC processes weak references &
28+
* nullifies reference -- points to an -- unmarked object
29+
* if you want to decrease the GC pause time -> enable the concurrent processing of weak references -- via -- `-Xbinary=concurrentWeakSweep=true` compilation option
1930

20-
When the marking phase is completed, the GC processes weak references and nullifies reference points to an unmarked object.
21-
To decrease the GC pause time, you can enable the concurrent processing of weak references by using
22-
the `-Xbinary=concurrentWeakSweep=true` compilation option.
23-
24-
The GC is executed on a separate thread and started based on the timer
25-
and memory pressure heuristics. Alternatively, it can be [called manually](#enable-garbage-collection-manually).
31+
* GC can be [called manually](#enable-garbage-collection-manually)
2632

2733
### Enable garbage collection manually
2834

29-
To force-start the garbage collector, call `kotlin.native.internal.GC.collect()`. This method triggers a new collection
30-
and waits for its completion.
35+
* call `kotlin.native.internal.GC.collect()`
36+
* -> triggers a new collection & waits for its completion
3137

3238
### Monitor GC performance
3339

34-
To monitor the GC performance, you can look through its logs and diagnose issues. To enable logging,
35-
set the following compiler option in the Gradle build script:
36-
37-
```none
38-
-Xruntime-logs=gc=info
39-
```
40-
41-
Currently, the logs are only printed to `stderr`.
42-
43-
On Apple platforms, you can take advantage of the Xcode Instruments toolkit to debug iOS app performance.
44-
The garbage collector reports pauses with signposts available in Instruments.
45-
Signposts enable custom logging within your app, allowing you to check if a GC pause corresponds to an application freeze.
46-
47-
To track GC-related pauses in your app:
40+
* if you want to enable logging -> set the following compiler option | Gradle build script
4841

49-
1. Open Xcode, go to **Product** | **Profile** or press <shortcut>Cmd + I</shortcut>. This action compiles your app and
50-
launches Instruments.
51-
2. In the template selection, select **os_signpost**.
52-
3. Configure it by specifying `org.kotlinlang.native.runtime` as **subsystem** and `safepoint` as **category**.
53-
4. Click the red record button to run your app and start recording signpost events:
42+
```none
43+
-Xruntime-logs=gc=info
44+
45+
// default
46+
//-Xruntime-logs=gc=error
47+
```
5448
55-
![Tracking GC pauses as signposts](native-gc-signposts.png){width=700}
49+
* | Apple platforms, use Xcode Instruments toolkit
50+
* way to track GC-related pauses
51+
1. Open Xcode, go to **Product** | **Profile** or press <shortcut>Cmd + I</shortcut>
52+
1. -> compiles your app & launches Instruments
53+
2. | template selection, select **os_signpost**
54+
3. specify `org.kotlinlang.native.runtime` as **subsystem** & `safepoint` as **category**
55+
4. Click the red record button to run your app and start recording signpost events
5656
57-
Here, each blue blob on the lowest graph represents a separate signpost event, which is a GC pause.
58-
59-
The feature is enabled by default. However, you can disable it with the `-Xbinary=enableSafepointSignposts=false`
60-
compiler option.
57+
![Tracking GC pauses as signposts](/docs/images/multiplatform/native-gc-signposts.png)
58+
* previous feature
59+
* enabled, by default
60+
* if you want to disable -> specify `-Xbinary=enableSafepointSignposts=false` compiler option
6161
6262
### Disable garbage collection
6363
64-
It's recommended to keep GC enabled. However, you can disable it in certain cases, such as for testing purposes or
65-
if you encounter issues and have a short-lived program. To do so, set the following compilation flag in the Gradle
66-
build script:
64+
* use cases to disable garbage collection
65+
* testing purposes
66+
* if you encounter issues & have a short-lived program
67+
* | Gradle build script
6768
68-
```none
69-
-Xgc=noop
70-
```
69+
```none
70+
-Xgc=noop
71+
```
7172
72-
> With this option enabled, the GC doesn't collect Kotlin objects, so memory consumption will keep rising as long as the
73-
> program runs. Be careful not to exhaust the system memory.
74-
>
75-
{type="warning"}
73+
* if it's disabled -> memory consumption will keep rising -> 👀careful NOT exhaust the system memory 👀
7674
7775
## Memory consumption
7876
79-
Kotlin/Native uses its own [memory allocator](https://github.com/JetBrains/kotlin/blob/master/kotlin-native/runtime/src/alloc/custom/README.md).
80-
It divides system memory into pages, allowing independent sweeping in consecutive order. Each allocation becomes a memory
81-
block within a page, and the page keeps track of block sizes. Different page types are optimized for various allocation
82-
sizes. The consecutive arrangement of memory blocks ensures efficient iteration through all allocated blocks.
83-
84-
When a thread allocates memory, it searches for a suitable page based on the allocation size. Threads maintain a set of
85-
pages for different size categories. Typically, the current page for a given size can accommodate the allocation.
86-
If not, the thread requests a different page from the shared allocation space. This page may already be available,
87-
require sweeping, or have to be created first.
88-
89-
The Kotlin/Native memory allocator comes with protection against sudden spikes in memory allocations. It prevents
90-
situations where the mutator starts to allocate a lot of garbage quickly and the GC thread cannot keep up with it,
91-
making the memory usage grow endlessly. In this case, the GC forces a stop-the-world phase until the iteration is completed.
92-
93-
You can monitor memory consumption yourself, check for memory leaks, and adjust memory consumption.
77+
* 💡Kotlin/Native uses its OWN [memory allocator](https://github.com/JetBrains/kotlin/blob/master/kotlin-native/runtime/src/alloc/custom/README.md) 💡/
78+
* 👀system memory -- is divided into -- pages 👀
79+
* -> sweeping
80+
* independent
81+
* in consecutive order
82+
* EACH allocation == memory block | page
83+
* the page -- keeps track of -- block sizes
84+
* DIFFERENT page types -- are optimized for -- various allocation sizes
85+
* consecutive arrangement of memory blocks -> efficient iteration | ALL allocated blocks
86+
* includes protection -- against -- sudden spikes | memory allocations
87+
* -> prevents certain situations
88+
* _Example:_ mutator starts to allocate a lot of garbage quickly & the GC thread can NOT keep up with it == memory usage grow endlessly
89+
* -> GC forces a stop-the-world phase | UNTIL the iteration is completed
90+
91+
* if a thread allocates memory -> the thread -- searches for a -- suitable page / -- based on the -- allocation size
92+
* threads maintain a set of pages / DIFFERENT size categories
93+
* current page / given size -- can accommodate the -- allocation
94+
* if not -> the thread -- from the shared allocation space, requests a -- different page /
95+
* this page MAY
96+
* already be available,
97+
* require sweeping, or
98+
* have to be created first
9499
95100
### Check for memory leaks
96101
102+
* TODO:
97103
To access the memory manager metrics, call `kotlin.native.internal.GC.lastGCInfo()`. This method returns statistics for the last
98104
run of the garbage collector. The statistics can be useful for:
99105

0 commit comments

Comments
 (0)