mirror of
https://github.com/bspeice/speice.io
synced 2024-11-05 01:28:09 -05:00
Continue drafting wor
This commit is contained in:
parent
b0fe32c4dc
commit
555eca2660
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
layout: post
|
layout: post
|
||||||
title: "Understanding Allocations"
|
title: "Understanding Heap Allocations in Rust"
|
||||||
description: "An introduction to the Rust memory model"
|
description: "An introduction to the Rust memory model"
|
||||||
category:
|
category:
|
||||||
tags: [rust]
|
tags: [rust]
|
||||||
@ -8,33 +8,72 @@ tags: [rust]
|
|||||||
|
|
||||||
There's an alchemy of distilling complex technical topics into articles and videos
|
There's an alchemy of distilling complex technical topics into articles and videos
|
||||||
that change the way programmers see the tools they interact with on a regular basis.
|
that change the way programmers see the tools they interact with on a regular basis.
|
||||||
I've known what a linker was, but there's a staggering complexity to get from
|
I knew what a linker was, but there's a staggering complexity to get from
|
||||||
[source code to `main()`](https://www.youtube.com/watch?v=dOfucXtyEsU). Rust programmers
|
[from `main()` to an executable](https://www.youtube.com/watch?v=dOfucXtyEsU).
|
||||||
use the [`Box`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html) type
|
Rust programmers use the [`Box`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html)
|
||||||
all the time, but there's a rich history of the Rust language itself wrapped up in
|
type all the time, but there's a rich history of the Rust language itself wrapped up in
|
||||||
[how special it is](https://manishearth.github.io/blog/2017/01/10/rust-tidbits-box-is-special/).
|
[how special it is](https://manishearth.github.io/blog/2017/01/10/rust-tidbits-box-is-special/).
|
||||||
|
|
||||||
In a similar vein, I want you to look at code and understand memory;
|
In a similar vein, I want you to look at code and understand memory;
|
||||||
the complex choreography of processor, operating system, and program that frees you
|
the complex choreography of processor, operating system, and program that frees you
|
||||||
to focus on functionality beyond rote book-keeping. The Rust compiler relieves a great deal
|
to focus on functionality far beyond frivolous book-keeping. The Rust compiler relieves
|
||||||
of the cognitive burden associated with memory management. Even so, let's make time
|
a great deal of the cognitive burden associated with memory management, but let's make time
|
||||||
to explore what's going on under the hood, so we can make better exploit the systems
|
to explore what's going on under the hood.
|
||||||
involved in the code we write.
|
|
||||||
|
|
||||||
Let's learn a bit about allocating memory in Rust.
|
Let's learn a bit about allocating memory in Rust.
|
||||||
|
|
||||||
# Table of Contents
|
# Table of Contents
|
||||||
|
|
||||||
This post is intended as both guide and reference material; we'll work to establish
|
This post is intended as both guide and reference material; we'll work to establish
|
||||||
an understanding of how Rust makes use of memory in a program, then summarize each
|
an understanding of the different memory types Rust makes use of, then summarize each
|
||||||
section for easy citation in the future. To that end, a table of contents is provided
|
section for easy citation in the future. To that end, a table of contents is provided
|
||||||
to assist in easy navigation:
|
to assist in easy navigation:
|
||||||
|
|
||||||
- [Distinguishing regions of memory](#distinguishing-regions-of-memory)
|
- [Foreword](#foreword)
|
||||||
- Rust and the Stack
|
- Non-Heap Memory Types
|
||||||
- Rust and the Heap
|
- Piling On - the Heap in Rust
|
||||||
- Understanding Compiler Optimizations
|
- Compiler Optimizations Make Everything Complicated
|
||||||
- Summary: When does Rust allocate?
|
- Summary: When Does Rust Allocate?
|
||||||
|
- Appendix and Further Reading
|
||||||
|
|
||||||
|
# Foreword
|
||||||
|
|
||||||
|
There's a simple way to guarantee you never need to know the content
|
||||||
|
of this article:
|
||||||
|
|
||||||
|
1. Only write `#![no_std]` crates
|
||||||
|
2. Never use `unsafe`
|
||||||
|
3. Never use `#![feature(alloc)]`
|
||||||
|
|
||||||
|
For some uses of Rust, typically embedded devices, these constraints make sense.
|
||||||
|
They're working with very limited memory, and the program binary size itself may
|
||||||
|
affect the memory available! There's no operating system able to manage the heap,
|
||||||
|
but that's not an issue because your program is likely the only one running.
|
||||||
|
The [embedonomicon] is ever in mind, and you just might interact with extra
|
||||||
|
peripherals by reading and writing to exact memory addresses.
|
||||||
|
|
||||||
|
Most Rust programs find these requirements overly burdensome though. C++ developers
|
||||||
|
would struggle without access to [`std::vector`](https://en.cppreference.com/w/cpp/container/vector),
|
||||||
|
and Rust developers would struggle without [`std::vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html).
|
||||||
|
But in this scenario, `std::vec` is actually part of the
|
||||||
|
[`alloc` crate](https://doc.rust-lang.org/alloc/vec/struct.Vec.html), and thus off-limits.
|
||||||
|
Or how would you use trait objects? Rust's monomorphization still works, but there's no
|
||||||
|
[`Box<dyn Trait>`](https://doc.rust-lang.org/alloc/boxed/struct.Box.html)
|
||||||
|
available to use for dynamic dispatch.
|
||||||
|
|
||||||
|
Given a target audience of "basically every Rust developer," let's talk about
|
||||||
|
some of the details you don't normally have to worry about. This article will focus
|
||||||
|
on "safe" Rust only; `unsafe` mode allows you to make use of platform-specific
|
||||||
|
allocation APIs (think [libc] and [winapi] implementations of [malloc]) that
|
||||||
|
we'll ignore for the time being. We'll also assume a "debug" build of libraries
|
||||||
|
and applications (what you get with `cargo run` and `cargo test`) and address
|
||||||
|
"release" mode at the end (`cargo run --release` and `cargo test --release`).
|
||||||
|
|
||||||
|
Finally, a caveat: while the details are unlikely to change, the Rust docs
|
||||||
|
include a warning worth repeating here:
|
||||||
|
|
||||||
|
> Rust does not currently have a rigorously and formally defined memory model.
|
||||||
|
> - the [Rust docs](https://doc.rust-lang.org/std/ptr/fn.read_volatile.html)
|
||||||
|
|
||||||
# Distinguishing regions of memory
|
# Distinguishing regions of memory
|
||||||
|
|
||||||
@ -61,7 +100,13 @@ Questions:
|
|||||||
1. Where do collection types allocate memory?
|
1. Where do collection types allocate memory?
|
||||||
2. Does a Box<> always allocate heap?
|
2. Does a Box<> always allocate heap?
|
||||||
3. Passing Box<Trait> vs. genericizing/monomorphization
|
3. Passing Box<Trait> vs. genericizing/monomorphization
|
||||||
|
4. Other pointer types? Do Rc<>/Arc<> force heap allocation?
|
||||||
|
|
||||||
# Understanding compiler optimizations
|
# Understanding compiler optimizations
|
||||||
|
|
||||||
Example: Compiler stripping out allocations of Box<>, Vec::push()
|
Example: Compiler stripping out allocations of Box<>, Vec::push()
|
||||||
|
|
||||||
|
[embedonomicon]: https://docs.rust-embedded.org/embedonomicon/
|
||||||
|
[libc]: CRATES.IO LINK
|
||||||
|
[winapi]: CRATES.IO LINK
|
||||||
|
[malloc]: MANPAGE LINK
|
Loading…
Reference in New Issue
Block a user