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