Week 2 - Memory Layout: Stack, Heap, Data, BSS, TLS¶
2.1 Conceptual Core¶
- A Rust value lives in exactly one of: a stack frame, the heap (via an allocator),
.data(mutable static),.rodata(immutable static /const),.bss(zero-initialized static), or thread-local storage. let x = 5;putsxon the stack.Box::new(5)puts the integer on the heap and a pointer on the stack.static X: i32 = 5;putsXin.rodata.static mut Y: i32 = 0;putsYin.data. Internalize this taxonomy before writing another line of code.constvsstatic:constis inlined at every use site (no address);statichas a stable address. The distinction matters for FFI and for sharing across threads.
2.2 Mechanical Detail¶
std::mem::size_of,align_of,size_of_val,align_of_val. Run them on(),bool,&u8,&[u8],&dyn Debug,Box<dyn Debug>,Option<&T>,Option<Box<T>>. Predict the answers, then check.- Niche optimization:
Option<&T>is 8 bytes, not 16, because the null pointer is the niche.Option<Box<T>>likewise. Learn to spot when you've broken the niche by adding a redundant variant. #[repr(C)],#[repr(transparent)],#[repr(packed)],#[repr(align(N))]: when each is appropriate. Default#[repr(Rust)]reorders fields for tightest packing-this is observable via - -print=type-sizes` (nightly).- Thread-local storage:
thread_local!macro, the OS-level cost (__tls_get_addron Linux glibc), and why it is rarely the right answer.
2.3 Lab-"Layout Forensics"¶
Build a binary that allocates one value of each "kind":
- a stack [u8; 64],
- a Box<[u8; 64]>,
- a static FOO: [u8; 64] = [0xAB; 64];,
- a static mut BAR: [u8; 64] = [0; 64];,
- a thread_local! RefCell<[u8; 64]>.
Print the address of each (&value as *const _ as usize). Run under cat /proc/self/maps (spawn cat from inside the program) and prove which segment each address falls in. Write up the mapping in NOTES.md.
2.4 Idiomatic & Clippy Drill¶
- Lints to study:
clippy::large_stack_arrays,clippy::large_enum_variant,clippy::box_collection,clippy::vec_box. Each maps to a layout pathology.
2.5 Production Hardening Slice¶
- Set
RUSTFLAGS="-C link-arg=-Wl,--print-memory-usage"(or usecargo-bloat) to inspect per-section binary footprint. Addcargo bloat --release --cratesoutput toNOTES.md. This is the baseline for size-budget conversations later.