liveBook · Manning

Memory allocation

As explained in Rust in Action: Systems programming concepts and techniques

Memory allocation is the process of reserving memory for data or program execution.

Memory allocation reserves space a program can use. With dynamic allocation, a running program requests more memory when it needs it, uses that memory, then releases it when it is no longer needed. An allocator sits between the program and the operating system and may satisfy a request without asking the OS to do more work. section 6.3.3

Where data lives changes the trade-off:

  • Stack-allocated local variables sit together in memory, making their layout cache-friendly. Stack data structures have less flexibility in size. section 6.3.3
  • Heap-allocated data is reached through a pointer and can be more flexible. Its layout and access costs help explain why allocation performance is worth measuring. section 6.3.3

Measure allocations

A graphical particle program creates and destroys heap objects while reporting each allocation’s size and duration. Redirect its stderr to alloc.tsv, then plot the results with gnuplot. Larger requests tend to take longer, but repeated requests of the same size can have very different timings. Measure before deciding that allocation costs matter to your program. section 6.3.3 section 6.3.4

Figure 6.8 Plotting heap allocation times against allocation size shows that there is no clear relationship between the two. The time taken to allocate memory is essentially unpredictable, even when requesting the same amount of memory multiple times.

The scatterplot makes the wide range of allocation times visible, including for requests of similar size. section 6.3.4

To reduce heap allocations, consider an allocator suited to the program’s memory-use pattern or an arena that obtains and releases memory in larger steps. Precreating zeroed objects is another strategy, but it can bypass Rust’s lifetime checks. In a kernel without an OS to provide dynamic allocation, avoid code that depends on it; #![no_std] also makes types such as Vec<T> unavailable. section 6.3.4 section 11.2.3

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Explains request-use-release, allocator mediation, and stack–heap trade-offs, then measures timings without implementing an allocator.
Examples
Measures heap-object creation in a graphical particle program and plots allocation size against duration with gnuplot.
What it assumes
Builds on local variables, pointers, and the stack–heap distinction while introducing allocator mediation.
What you can do after
Diagnose/debug with it by recording allocation timings, plotting them, and considering whether fewer heap allocations would help.
How it connects
Links allocation to the stack, heap, pointers, CPU caches, allocators, and operating-system requests.

Also explained in

Compare how 11 books explain memory allocation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.