Fundamentals 21 min read

Inside iOS: How Mach Virtual Memory and Memory Pressure Work

This article explains the architecture of Mach virtual memory in iOS, details its page‑based management, describes the core data structures and kernel APIs, analyzes the Objective‑C alloc implementation, and walks through the memory‑pressure (Jetsam) mechanism that triggers low‑memory warnings.

Baidu App Technology
Baidu App Technology
Baidu App Technology
Inside iOS: How Mach Virtual Memory and Memory Pressure Work

Mach Virtual Memory Overview

iOS is built on the Darwin kernel (XNU), which combines the Mach micro‑kernel, BSD, and I/O Kit. Mach handles the lowest‑level tasks such as process/thread abstraction, CPU scheduling, inter‑process communication, and, crucially, virtual memory management.

Key Characteristics of Mach Virtual Memory

Mach uses a page‑based virtual memory system. On ARM64 iOS devices the default page size is 16 KB (instead of the typical 4 KB on Intel/ARM). Commands like hw.pagesize and vm_stat can be used to query page size and free page counts.

iOS does not provide a swap partition; when physical RAM runs low the system relies on memory compression and the Jetsam mechanism rather than paging to disk.

Memory Compression

Since OS X Mavericks (10.9) and iOS 7, the kernel can compress inactive pages, reducing their footprint to roughly half of the original size. The compressed memory metric must be recorded alongside regular page statistics.

Memory‑Pressure (Jetsam) Mechanism

When memory compression cannot free enough RAM, the kernel sends a NOTE_VM_PRESSURE notification to the process holding the most resident pages. The app receives didReceiveMemoryWarning and should release caches to avoid an OOM kill.

The Jetsam subsystem, similar to Linux’s OOM killer, selects a victim based on priority: kernel threads > system services > foreground apps > background apps.

Core Mach Memory Data Structures

The virtual memory layer is built around four structures:

vm_map : Represents an address space; composed of a doubly‑linked list of vm_map_entry objects.

vm_map_entry : Describes a contiguous virtual region and its protection flags; points to a vm_object.

vm_object : Links a map entry to actual physical pages; contains a list of vm_page, flags, and reference counters.

vm_page : Holds the physical page metadata (offset, state bits such as resident, dirty, compressed, etc.).

All structures are defined in the open‑source XNU tree (e.g., osfmk/vm/vm_map.h, osfmk/vm/vm_object.h, osfmk/vm/vm_page.h).

Kernel Memory Operation APIs

The Mach kernel exposes a set of mach_vm_* functions for allocation, deallocation, protection, mapping, and page queries. libsystem_malloc.dylib bridges the gap between these kernel calls and the higher‑level malloc / free used by applications.

mach_vm_allocate   // allocates zero‑filled memory in a map
mach_vm_deallocate // frees a range of addresses
mach_vm_protect   // changes protection bits
mach_vm_map       // maps a memory object into a task
mach_vm_page_query// queries page information

Objective‑C alloc Source Analysis

The allocation path starts at + (id)alloc, which forwards to _objc_rootAlloc and then to callAlloc. After checking for a custom allocWithZone: implementation, the runtime eventually calls _class_createInstanceFromZone to allocate the object.

+ (id)alloc { return _objc_rootAlloc(self); }

static ALWAYS_INLINE id callAlloc(Class cls, bool checkNil, bool allocWithZone) {
    if (slowpath(checkNil && !cls)) return nil;
    if (fastpath(!cls->ISA->hasCustomAWZ())) {
        return _objc_rootAllocWithZone(cls, nil);
    }
    /* … */
}

NEVER_INLINE id _objc_rootAllocWithZone(Class cls, malloc_zone_t *zone) {
    return _class_createInstanceFromZone(cls, 0, nil, OBJECT_CONSTRUCT_CALL_BADALLOC);
}

The core routine computes the instance size via instanceSize, aligns it to 16‑byte boundaries, and finally allocates memory with calloc or malloc_zone_calloc:

size_t size = cls->instanceSize(extraBytes);
if (zone) obj = (id)malloc_zone_calloc(zone, 1, size);
else       obj = (id)calloc(1, size);

Memory‑Pressure Thread Implementation

During kernel bootstrap, vm_pageout() creates the VM_pressure daemon thread. The thread sleeps on vm_pressure_thread and wakes when vm_pressure_response() updates the global memorystatus_vm_pressure_level based on several macros that compare available (compressed + non‑compressed) memory against thresholds.

void vm_pressure_response(void) {
    switch (memorystatus_vm_pressure_level) {
        case kVMPressureNormal:
            if (VM_PRESSURE_WARNING_TO_CRITICAL()) new_level = kVMPressureCritical;
            else if (VM_PRESSURE_NORMAL_TO_WARNING()) new_level = kVMPressureWarning;
            break;
        /* … other cases … */
    }
    if (new_level != -1) {
        memorystatus_vm_pressure_level = (vm_pressure_level_t)new_level;
        if (vm_pageout_state.vm_pressure_thread_running == FALSE) {
            thread_wakeup(&vm_pressure_thread);
        }
    }
}

The response routine evaluates macros such as VM_PRESSURE_NORMAL_TO_WARNING() (non‑compressed memory < ½ of total) and VM_PRESSURE_WARNING_TO_CRITICAL() (non‑compressed memory < 12/40 of total). When the level changes, the daemon selects a candidate process via vm_pressure_select_optimal_candidate_to_notify and sends a NOTE_MEMORYSTATUS_PRESSURE_WARN or NOTE_MEMORYSTATUS_PRESSURE_CRITICAL notification, which the app receives as a memory‑warning callback.

Conclusion

The article covered Mach’s virtual‑memory architecture, its key data structures, the kernel‑level memory APIs, the Objective‑C allocation path, and the complete source‑level flow of iOS’s memory‑pressure (Jetsam) system. Future posts will dive deeper into Jetsam internals and the libsystem_malloc implementation.

Mach memory diagram
Mach memory diagram
Page size illustration
Page size illustration
iOS memory layout
iOS memory layout
Memory‑pressure flowchart
Memory‑pressure flowchart
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSmemory-managementKernelVirtual MemorySource codeMach
Baidu App Technology
Written by

Baidu App Technology

Official Baidu App Tech Account

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.