3.10 · Enum layout, existential boxing, tail allocation, slice retention, growth and the command-line tools
More of what memory physically looks like and how to look at it: how small enums and optionals pack, when a protocol value hits the heap, why a slice can pin a large array, and which tools inspect a process.
Mental model. Know three numbers for any type, size, stride and whether it allocates, and know one command for each way a process can hold memory.
Packing and boxing
Extra inhabitants, existential buffers and tail allocation.
- Why is Optional
nine bytes but Optional eight, and how do enums choose their layout?
A value’s bit pattern often has spare patterns that no valid value uses (extra inhabitants), and Swift stores enum cases and nil in them when it can. A class… - How big is an any Protocol value, and when does storing one allocate on the heap?
An any P for a non-class protocol is a 40-byte container on 64-bit: a three-word inline buffer for the value, a pointer to the type’s metadata, and a pointer… - What is ManagedBuffer, and how does tail allocation put a header and elements in one allocation?
ManagedBuffer<Header, Element> is a class whose instances are allocated with extra storage after the object (tail allocation). One malloc holds the 16-byte…
Growth and inspection
Slices that pin buffers, capacity rules and the macOS inspection tools.
- Why can a small slice keep a large array (or string) alive, and how do you stop it?
An ArraySlice or Substring is a view onto the original buffer: it stores a range and a reference to the parent storage. The elements outside the range stay… - How do Array capacity and growth work, and when does an array give memory back?
An array has a count and a capacity. When an append exceeds capacity the array allocates a bigger buffer and moves the elements; the growth is geometric (the… - Which command-line tools inspect a running process’s memory on macOS: leaks, heap, footprint and vmmap?
Instruments is the friendly front end, but every view is also a command that you can script in CI or run on a Mac app or a simulator process (xcrun simctl…
More in Memory, ARC & runtime
- 3.1 · ARC, autorelease pools, object lifetime
- 3.2 · strong, weak, unowned, unowned(unsafe)
- 3.3 · Cycles: delegates, closures, timers, Combine, tasks
- 3.4 · Object layout, side tables, tagged pointers
- 3.5 · The copy-on-write mechanism
- 3.6 · Retain traffic, parameter conventions, Unmanaged, bridging
- 3.7 · Leaks, abandoned memory, footprint, and the tools
- 3.8 · deinit rules, process exit, isolated deinit, noncopyable types and consume
- 3.9 · Weak collections, nested closures, structs holding references, weak let and escaped pointers