Asynchronous pin release 2026-11-05
Asynchronous pin release ends the address-stability guarantee for a pinned memory object after an operation that can continue beyond its submission call. Its central condition is that no unfinished consumer may still access the pinned address. Returning from submission is sufficient only when the operation's contract says that all access has ended. Microsoft's asynchronous native-call example stores the pin handle in callback state and disposes it during completion cleanup.[ref]
Memory and Span usage guidelines by Microsoft. Rule10, asynchronous native-call wrapper and completion callback
For an original event sequence, suppose an operation acquires a pin at0ms, submits at1ms, returns a pending result at2ms and finishes its last access at8ms. Completion cleanup at8ms can end the pinning lifetime; cleanup at2ms cannot. If a request to stop arrives at3ms but the operation acknowledges completion only at6ms, the request alone does not authorize release at3ms. The actual access contract, rather than the desired outcome, determines when the address may change.
An implementation needs a single owner for cleanup across all completion paths. Submission might fail before any callback is promised, complete immediately, or complete later. Each path must transfer or retain the cleanup responsibility consistently. The exactly-once pin cleanup requirement avoids both leaking a pin and releasing the same handle twice. The primary Microsoft example explicitly cleans up an exception before a callback can be invoked, and funnels immediate and deferred completion through a completion routine.[ref]
Memory and Span usage guidelines by Microsoft. Rule10, exception cleanup and non-pending completion branch
With overlapping users, releasing one operation's interest does not establish that every user has finished. A reference counting protocol can track outstanding access leases, provided starting new work and deciding that the last lease ended are synchronized. An observed zero count without protection against a simultaneous new user is not sufficient. A mutex or another appropriate synchronization mechanism can protect that transition.
The completion signal must itself describe the end of access. Microsoft's task-based buffer rule forbids a consumer from continuing to use the memory after the returned task reaches a terminal state.[ref]
Memory and Span usage guidelines by Microsoft. Rule4, consumer lifetime and task terminal state
An API that reports cancellation before its underlying user has stopped requires another completion guarantee before pin cleanup. Retaining the pin protects the address; it does not by itself prevent concurrent data races or determine who may reuse the buffer. Movable memory object 2026-11-05
A movable memory object is a live allocation that its memory-management system may relocate while preserving its identity and valid references. Moving the stored bytes is only part of the operation: references must be updated, or an indirection mechanism must continue to locate the object. This capability permits memory compaction. Microsoft's primary runtime documentation describes separate marking, reference-relocation and object-compaction phases of garbage collection.[ref]
Fundamentals of garbage collection by Microsoft. “What happens during a garbage collection”, marking, relocating and compacting phases
For an illustrative16-byte object initially starting at offset24, compaction may place its bytes at offset0. A reference to its beginning then changes from24 to0; a reference five bytes inside it changes from29 to5. In general, moving the base from to maps a tracked interior reference to . An unrelated integer with value29 must not be rewritten merely because it resembles the old address.
The memory manager therefore needs reliable knowledge of roots and references, including those held in other live objects. A garbage collection root can keep an object reachable while its address changes. If an external consumer requires the address to stay fixed, a pinned memory object imposes a relocation constraint instead. Movability is a property of the reference-management arrangement, not simply of whether the object contains bytes that can be copied.
A raw C programming language pointer returned by an ordinary allocator generally prevents arbitrary hidden movement, because the allocator does not control all copies of that address.[ref]
Operating Systems: Three Easy Pieces by Remzi H. Arpaci-Dusseau and others. Chapter17, §17.1, nonrelocation assumption and tracked-reference discussion, printed pp.2–3
Physical-page movement under virtual memory is another layer: an operating system may preserve virtual addresses while changing the underlying physical mapping. It need not make the application-level object movable in its own address space. Pinned memory object 2026-11-05
A pinned memory object is a normally movable memory object whose address must remain unchanged during a specified operation. Pinning permits a pointer to remain usable when the code consuming it cannot participate in the runtime's relocation of references. The pinning lifetime is part of that guarantee: an address retained beyond the protected operation need not remain valid. Microsoft's language reference specifies that a
fixed statement prevents relocation during its body and restricts the declared pointer to that statement.[ref]Fixed statement in the C reference by Microsoft. Opening definition; array-element and object-field guarantees
For an original layout example, consider96 bytes with a pinned16-byte object at offsets and one other16-byte live object. The remaining64 bytes are free. Even if the other object can move anywhere, the pinned object divides the address range into regions of32 and48 bytes. A56-byte contiguous allocation cannot fit. Moving the other object into gives free intervals and , whose largest size is48 bytes. If both live objects could move, placing them in would instead leave a64-byte interval. Pinning can therefore limit memory compaction despite ample total free capacity.
The numerical layout omits allocation headers and memory alignment; a real allocator must include them. Pinning an object's address also does not by itself specify how its virtual memory pages are backed. The garbage collector's object-relocation guarantee and an operating system's physical-page residency rules concern different layers. Likewise, a pinned buffer in a storage cache may mean protection from eviction rather than this object-relocation guarantee.
Once the protected operation is finished, releasing its pin can restore the runtime's freedom to move the object during a later collection. The program still has to obey the language's reference-lifetime rules: releasing a pin does not convert an old unmanaged address into a relocatable reference. The general garbage collection process must update references when it moves surviving objects.[ref]
Fundamentals of garbage collection by Microsoft. “What happens during a garbage collection”, relocating and compacting phases
Pinning lifetime 2026-11-05
The pinning lifetime is the interval during which a pinned memory object must retain its address for all consumers entitled to use a non-relocatable pointer into it. The interval must cover actual memory access, rather than merely the act of handing out the address. Microsoft's
fixed statement guarantees address stability during its body and restricts its declared pointer to that statement; a pointer retained for later work needs a guarantee covering that later work too.[ref]Fixed statement in the C reference by Microsoft. Opening definition and array-element/object-field lifetime guarantees
For an original timing example, suppose a pin starts at0ms, an external operation receives the address at0.5ms, its submission function returns at1ms, and its final memory access finishes at5ms. Releasing the pin at the function's return leaves4ms of possible access after address stability has ended. Releasing it only after completion at5ms can cover the whole access interval. These times describe an illustrative protocol, not a timing claim about a particular runtime or device.
If the pin is active on , every access time must satisfy . With several users, the release point must follow the last access by all of them. A count of outstanding operations can enforce this rule: after two operations start, one completion changes the count from2 to1 and does not permit release; the last completion changes1 to0. Asynchronous pin release therefore depends on a completion guarantee. Requesting that unfinished work stop does not by itself demonstrate that its final access has ended.
The pinning lifetime and data synchronization solve different problems. Stable addresses do not prevent two users from changing the same bytes concurrently; a mutex or another synchronization mechanism may still be needed. Nor should a pin be held indefinitely just because longer protection seems convenient: pinning can obstruct memory compaction, as the pinned memory object layout example shows. The useful interval is long enough for the access contract and ends when that contract permits release.