xref: /xnu-11215.1.10/doc/vm/memorystatus_notify.md (revision 8d741a5de7ff4191bf97d57b9f54c2f6d4a15585)
1*8d741a5dSApple OSS Distributions# Memorystatus Notifications
2*8d741a5dSApple OSS Distributions
3*8d741a5dSApple OSS DistributionsThis document details the notifications published by the memorystatus subsystem to userspace.
4*8d741a5dSApple OSS Distributions
5*8d741a5dSApple OSS Distributions## Dispatch Sources
6*8d741a5dSApple OSS Distributions
7*8d741a5dSApple OSS DistributionsHandlers can be registered for pressure and limit notifications via the
8*8d741a5dSApple OSS Distributionscreation of a dispatch source of type `DISPATCH_SOURCE_TYPE_MEMORYPRESSURE`.
9*8d741a5dSApple OSS DistributionsSee `dispatch_source_create(3)`.
10*8d741a5dSApple OSS Distributions
11*8d741a5dSApple OSS DistributionsUIKit further exposes handlers for App
12*8d741a5dSApple OSS Distributionsdevelopers. See
13*8d741a5dSApple OSS Distributions[Responding to Low Memory Warnings](https://developer.apple.com/documentation/xcode/responding-to-low-memory-warnings).
14*8d741a5dSApple OSS Distributions
15*8d741a5dSApple OSS Distributions## Memory Limits
16*8d741a5dSApple OSS Distributions
17*8d741a5dSApple OSS DistributionsProcesses may subscribe to notifications regarding memory limits.
18*8d741a5dSApple OSS Distributions
19*8d741a5dSApple OSS Distributions| Type     | Knote Flags                             | Dispatch Source Mask                          | Description                                                                         |
20*8d741a5dSApple OSS Distributions| -------- | --------------------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------- |
21*8d741a5dSApple OSS Distributions| WARN     | `NOTE_MEMORYSTATUS_PROC_LIMIT_WARN`     | `DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN`     | Process is within 100 MB of its memory limit.                                       |
22*8d741a5dSApple OSS Distributions| CRITICAL | `NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL` | `DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL` | Process has violated memory limit. Only sent if the memory limit is non-fatal/soft. |
23*8d741a5dSApple OSS Distributions
24*8d741a5dSApple OSS Distributions## Memory Pressure
25*8d741a5dSApple OSS Distributions
26*8d741a5dSApple OSS DistributionsThe kernel tracks its current "pressure level" via
27*8d741a5dSApple OSS Distributions`memorystatus_vm_pressure_level`. There are 5 distinct levels of pressure:
28*8d741a5dSApple OSS Distributions
29*8d741a5dSApple OSS Distributions| Level      | Value | Knote Flags                           | Dispatch Source Mask               | Description                                                                              |
30*8d741a5dSApple OSS Distributions| ---------- | ----- | ------------------------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------- |
31*8d741a5dSApple OSS Distributions| `Normal`   | 0     | `NOTE_MEMORYSTATUS_PRESSURE_NORMAL`   | `DISPATCH_MEMORYPRESSURE_NORMAL`   | Device is operating normally. No action is required.                                     |
32*8d741a5dSApple OSS Distributions| `Warning`  | 1     | `NOTE_MEMORYSTATUS_PRESSURE_WARN`     | `DISPATCH_MEMORYPRESSURE_WARN`     | Device is beginning to experience memory pressure. Consider relaxing caching policy.     |
33*8d741a5dSApple OSS Distributions| `Urgent`   | 2     | N/A                                   | N/A                                | Synonymous with `Warning`.                                                               |
34*8d741a5dSApple OSS Distributions| `Critical` | 3     | `NOTE_MEMORYSTATUS_PRESSURE_CRITICAL` | `DISPATCH_MEMORYPRESSURE_CRITICAL` | Device is in a critical memory state. Expect latencies and consider dropping all caches. |
35*8d741a5dSApple OSS Distributions| `Jetsam`\* | 4     | `NOTE_MEMORYSTATUS_JETSAM_FG_BAND`    | `N/A`                              | Jetsam is approaching the FOREGROUND band.                                               |
36*8d741a5dSApple OSS Distributions
37*8d741a5dSApple OSS Distributions\*`Jetsam` is only subscribable by kernel threads.
38*8d741a5dSApple OSS Distributions
39*8d741a5dSApple OSS Distributions### Available Memory
40*8d741a5dSApple OSS Distributions
41*8d741a5dSApple OSS DistributionsThe VM monitors the amount of "available memory" , which comprises the following:
42*8d741a5dSApple OSS Distributions
43*8d741a5dSApple OSS Distributions```
44*8d741a5dSApple OSS DistributionsAVAILABLE_NON_COMPRESSED_MEMORY = (active + inactive + free + speculative)
45*8d741a5dSApple OSS DistributionsAVAILABLE_MEMORY = (AVAILABLE_NON_COMPRESSED_MEMORY + compressed)
46*8d741a5dSApple OSS Distributions```
47*8d741a5dSApple OSS Distributions
48*8d741a5dSApple OSS DistributionsIn other words, `AVAILABLE_NON_COMPRESSED_MEMORY` tracks all of the memory on
49*8d741a5dSApple OSS Distributionsthe system that is either free or reclaimable (everything that is not either
50*8d741a5dSApple OSS Distributionswired, compressed, or stolen). `AVAILABLE_MEMORY` tracks all memory that
51*8d741a5dSApple OSS Distributionsis reclaimable, free, or being used to store compressed anonymous memory (i.e.
52*8d741a5dSApple OSS Distributionsnot wired or stolen). Compressed anonymous memory may be further "reclaimed"
53*8d741a5dSApple OSS Distributionsvia swapping or compaction, and thus is considered "available".
54*8d741a5dSApple OSS Distributions
55*8d741a5dSApple OSS Distributions### Pressure Thresholds
56*8d741a5dSApple OSS Distributions
57*8d741a5dSApple OSS DistributionsPressure states are triggered when `AVAILABLE_NON_COMPRESSED_MEMORY` dips
58*8d741a5dSApple OSS Distributionsbelow the following thresholds:
59*8d741a5dSApple OSS Distributions
60*8d741a5dSApple OSS Distributions| Level       | Rising Threshold                                     | Falling Threshold                                    |
61*8d741a5dSApple OSS Distributions| ----------- | ---------------------------------------------------- | ---------------------------------------------------- |
62*8d741a5dSApple OSS Distributions| `Warning`   | `VM_PAGE_COMPRESSOR_COMPACT_THRESHOLD`               | `1.2 * VM_PAGE_COMPRESSOR_COMPACT_THRESHOLD`         |
63*8d741a5dSApple OSS Distributions| `Critical`  | `1.2 * VM_PAGE_COMPRESSOR_SWAP_UNTHROTTLE_THRESHOLD` | `1.4 * VM_PAGE_COMPRESSOR_SWAP_UNTHROTTLE_THRESHOLD` |
64*8d741a5dSApple OSS Distributions
65*8d741a5dSApple OSS DistributionsThese thresholds are described by:
66*8d741a5dSApple OSS Distributions
67*8d741a5dSApple OSS Distributions| Threshold                                      | Embedded Value            | macOS Value               | Description                                               |
68*8d741a5dSApple OSS Distributions| ---------------------------------------------- | ------------------------- | ------------------------- | --------------------------------------------------------- |
69*8d741a5dSApple OSS Distributions| `VM_PAGE_COMPRESSOR_COMPACT_THRESHOLD`         | `0.5 * AVAILABLE_MEMORY`  | `0.5 * AVAILABLE_MEMORY`  | Initiate minor-compaction of compressed segments.         |
70*8d741a5dSApple OSS Distributions| `VM_PAGE_COMPRESSOR_SWAP_THRESHOLD`            | `0.3 * AVAILABLE_MEMORY`  | `0.4 * AVAILABLE_MEMORY`  | Begin major-compaction & swapping of compressed segments. |
71*8d741a5dSApple OSS Distributions| `VM_PAGE_COMPRESSOR_SWAP_UNTHROTTLE_THRESHOLD` | `0.25 * AVAILABLE_MEMORY` | `0.29 * AVAILABLE_MEMORY` | Un-throttle the swapper thread.                           |
72*8d741a5dSApple OSS Distributions
73*8d741a5dSApple OSS Distributions###  Kernel Monitoring
74*8d741a5dSApple OSS Distributions
75*8d741a5dSApple OSS DistributionsKernel/kext threads may monitor the system pressure level via
76*8d741a5dSApple OSS Distributions`mach_vm_pressure_level_monitor()` which allows the current pressure level to
77*8d741a5dSApple OSS Distributionsbe queried or the calling thread to block until the pressure level changes.
78*8d741a5dSApple OSS Distributions
79*8d741a5dSApple OSS Distributions### Differences from Jetsam
80*8d741a5dSApple OSS Distributions
81*8d741a5dSApple OSS DistributionsThe jetsam control loop monitors a different measure of "available" memory
82*8d741a5dSApple OSS Distributions(`memorystatus_available_pages`, see [memorystatus.md](memorystatus.md)).
83*8d741a5dSApple OSS DistributionsThis available page count is the subset of `AVAILABLE_NON_COMPRESSED_MEMORY`
84*8d741a5dSApple OSS Distributionsthat is fully-reclaimable -- (file-backed + free + secluded-over-target +
85*8d741a5dSApple OSS Distributionspurgeable). Jetsam monitors the ratio of these fully-reclaimable pages to
86*8d741a5dSApple OSS Distributions_all_ pages (max_mem), rather than only "available" pages as monitored for
87*8d741a5dSApple OSS Distributionspressure.
88*8d741a5dSApple OSS Distributions
89*8d741a5dSApple OSS DistributionsThe design goals of jetsam and vm_pressure can be thought of in the following
90*8d741a5dSApple OSS Distributionsway.
91*8d741a5dSApple OSS Distributions
92*8d741a5dSApple OSS DistributionsJetsam attempts to maintain a sufficiently large pool of
93*8d741a5dSApple OSS Distributionsfully-reclaimable memory to satisfy transient spikes in page demand. This pool
94*8d741a5dSApple OSS Distributionsneed not be overly large; thus jetsam thresholds are generally on the order of
95*8d741a5dSApple OSS Distributions5%/10%/15% of max_mem.
96*8d741a5dSApple OSS Distributions
97*8d741a5dSApple OSS DistributionsConversely, vm_pressure attempts to maintain the amount of memory available to
98*8d741a5dSApple OSS Distributionsthe working set of processes. On a healthy system, this should be at least a
99*8d741a5dSApple OSS Distributionsmajority of the memory not otherwise wired down or stolen by the operating
100*8d741a5dSApple OSS Distributionssystem. If overall memory demand is such that, even with compression, the
101*8d741a5dSApple OSS Distributionsworking set no longer fits in available memory, then the system begins making
102*8d741a5dSApple OSS Distributionsroom by notifying processes, dropping caches, defragmenting the compressor pool,
103*8d741a5dSApple OSS Distributionsand swapping to disk.
104*8d741a5dSApple OSS Distributions
105*8d741a5dSApple OSS Distributions## Low Swap Notifications (macOS only)
106*8d741a5dSApple OSS Distributions
107*8d741a5dSApple OSS DistributionsWhen the compressor has exhausted its available space (VA or compressed-pages
108*8d741a5dSApple OSS Distributionslimit), it will notify registered process via `NOTE_MEMORYSTATUS_LOW_SWAP` /
109*8d741a5dSApple OSS Distributions`DISPATCH_MEMORYPRESSURE_LOW_SWAP`. This notification is restricted to the
110*8d741a5dSApple OSS Distributionsroot user.
111*8d741a5dSApple OSS Distributions
112*8d741a5dSApple OSS Distributions## MallocStackLogging
113*8d741a5dSApple OSS Distributions
114*8d741a5dSApple OSS DistributionsMallocStackLogging (MSL) can enabled/disabled via the same memorystatus knote.
115*8d741a5dSApple OSS DistributionsThe mask is `NOTE_MEMORYSTATUS_MSL_STATUS`/`DISPATCH_MEMORYPRESSURE_MSL_STATUS`.
116*8d741a5dSApple OSS Distributionslibdispatch registers a source with this type for all processes with a handler
117*8d741a5dSApple OSS Distributionsthat calls into libmalloc to enable/disable MSL.
118