mirror of
				https://github.com/bspeice/speice.io
				synced 2025-11-04 02:20:36 -05:00 
			
		
		
		
	First cleanup pass on the foreword
This commit is contained in:
		@ -9,12 +9,12 @@ tags: [rust, understanding-allocations]
 | 
				
			|||||||
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 knew what a linker was, but there's a staggering amount of complexity in between
 | 
					I knew what a linker was, but there's a staggering amount of complexity in between
 | 
				
			||||||
[`main()` and your executable](https://www.youtube.com/watch?v=dOfucXtyEsU).
 | 
					[the OS and `main()`](https://www.youtube.com/watch?v=dOfucXtyEsU).
 | 
				
			||||||
Rust programmers use the [`Box`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html)
 | 
					Rust programmers use the [`Box`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html)
 | 
				
			||||||
type 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 how memory is used;
 | 
					In a similar vein, this series attempts to look at code and understand how memory is used;
 | 
				
			||||||
the complex choreography of operating system, compiler, and program that frees you
 | 
					the complex choreography of operating system, compiler, and program that frees you
 | 
				
			||||||
to focus on functionality far-flung from frivolous book-keeping. The Rust compiler relieves
 | 
					to focus on functionality far-flung from frivolous book-keeping. The Rust compiler relieves
 | 
				
			||||||
a great deal of the cognitive burden associated with memory management, but we're going
 | 
					a great deal of the cognitive burden associated with memory management, but we're going
 | 
				
			||||||
@ -24,9 +24,10 @@ Let's learn a bit about 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 series is intended as both learning and reference material; we'll work through the
 | 
				
			||||||
an understanding of the different memory types Rust makes use of, then summarize each
 | 
					different memory types Rust uses, and explain the implications of each. Ultimately,
 | 
				
			||||||
section at the end for easy future citation. To that end, a table of contents is in order:
 | 
					a summary will be provided as a cheat sheet for easy future reference. To that end,
 | 
				
			||||||
 | 
					a table of contents is in order:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Foreword
 | 
					- Foreword
 | 
				
			||||||
- [Global Memory Usage: The Whole World](/2019/02/the-whole-world)
 | 
					- [Global Memory Usage: The Whole World](/2019/02/the-whole-world)
 | 
				
			||||||
@ -38,26 +39,28 @@ section at the end for easy future citation. To that end, a table of contents is
 | 
				
			|||||||
# Foreword
 | 
					# Foreword
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Rust's three defining features of [Performance, Reliability, and Productivity](https://www.rust-lang.org/)
 | 
					Rust's three defining features of [Performance, Reliability, and Productivity](https://www.rust-lang.org/)
 | 
				
			||||||
are all driven to a great degree by the how the Rust compiler understands
 | 
					are all driven to a great degree by the how the Rust compiler understands memory usage.
 | 
				
			||||||
[memory ownership](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html). Unlike managed memory
 | 
					Unlike managed memory languages (Java, Python), Rust
 | 
				
			||||||
languages (Java, Python), Rust [doesn't really](https://words.steveklabnik.com/borrow-checking-escape-analysis-and-the-generational-hypothesis)
 | 
					[doesn't really](https://words.steveklabnik.com/borrow-checking-escape-analysis-and-the-generational-hypothesis)
 | 
				
			||||||
garbage collect, leading to fast code when [dynamic (heap) memory](https://en.wikipedia.org/wiki/Memory_management#Dynamic_memory_allocation)
 | 
					garbage collect; instead, it uses an [ownership](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)
 | 
				
			||||||
isn't necessary. When heap memory is necessary, Rust ensures you can't accidentally mis-manage it.
 | 
					system to reason about how long objects will last in your program. In some cases, if the life of an object
 | 
				
			||||||
And because the compiler handles memory "ownership" for you, developers never need to worry about
 | 
					is fairly transient, Rust can make use of a very fast region called the "stack." When that's not possible,
 | 
				
			||||||
accidentally deleting data that was needed somewhere else.
 | 
					Rust uses [dynamic (heap) memory](https://en.wikipedia.org/wiki/Memory_management#Dynamic_memory_allocation)
 | 
				
			||||||
 | 
					and the ownership system to ensure you can't accidentally corrupt memory. It's not as fast, but it is
 | 
				
			||||||
 | 
					important to have available.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
That said, there are situations where you won't benefit from work the Rust compiler is doing.
 | 
					That said, there are specific situations in Rust where you'd never need to worry about the stack/heap
 | 
				
			||||||
If you:
 | 
					distinction! If you:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Never use `unsafe`
 | 
					1. Never use `unsafe`
 | 
				
			||||||
2. Never use `#![feature(alloc)]` or the [`alloc` crate](https://doc.rust-lang.org/alloc/index.html)
 | 
					2. Never use `#![feature(alloc)]` or the [`alloc` crate](https://doc.rust-lang.org/alloc/index.html)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
...then it's not possible for you to use dynamic memory! 
 | 
					...then it's not possible for you to use dynamic memory! 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For some uses of Rust, typically embedded devices, these constraints make sense.
 | 
					For some uses of Rust, typically embedded devices, these constraints are OK.
 | 
				
			||||||
They have very limited memory, and the program binary size itself may significantly
 | 
					They have very limited memory, and the program binary size itself may significantly
 | 
				
			||||||
affect what's available! There's no operating system able to manage
 | 
					affect what's available! There's no operating system able to manage
 | 
				
			||||||
this ["virtual memory"](https://en.wikipedia.org/wiki/Virtual_memory) junk, but that's
 | 
					this ["virtual memory"](https://en.wikipedia.org/wiki/Virtual_memory) thing, but that's
 | 
				
			||||||
not an issue because there's only one running application. The
 | 
					not an issue because there's only one running application. The
 | 
				
			||||||
[embedonomicon](https://docs.rust-embedded.org/embedonomicon/preface.html) is ever in mind,
 | 
					[embedonomicon](https://docs.rust-embedded.org/embedonomicon/preface.html) is ever in mind,
 | 
				
			||||||
and interacting with the "real world" through extra peripherals is accomplished by
 | 
					and interacting with the "real world" through extra peripherals is accomplished by
 | 
				
			||||||
@ -66,8 +69,8 @@ reading and writing to [specific memory addresses](https://bob.cs.sonoma.edu/Int
 | 
				
			|||||||
Most Rust programs find these requirements overly burdensome though. C++ developers
 | 
					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)
 | 
					would struggle without access to [`std::vector`](https://en.cppreference.com/w/cpp/container/vector)
 | 
				
			||||||
(except those hardcore no-STL people), and Rust developers would struggle without
 | 
					(except those hardcore no-STL people), and Rust developers would struggle without
 | 
				
			||||||
[`std::vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html). But in this scenario,
 | 
					[`std::vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html). But with the constraints above,
 | 
				
			||||||
`std::vec` is actually aliased to a part of the
 | 
					`std::vec` is actually a part of the
 | 
				
			||||||
[`alloc` crate](https://doc.rust-lang.org/alloc/vec/struct.Vec.html), and thus off-limits.
 | 
					[`alloc` crate](https://doc.rust-lang.org/alloc/vec/struct.Vec.html), and thus off-limits.
 | 
				
			||||||
`Box`, `Rc`, etc., are also unusable for the same reason.
 | 
					`Box`, `Rc`, etc., are also unusable for the same reason.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -75,11 +78,10 @@ Whether writing code for embedded devices or not, the important thing in both si
 | 
				
			|||||||
is how much you know *before your application starts* about what its memory usage will look like.
 | 
					is how much you know *before your application starts* about what its memory usage will look like.
 | 
				
			||||||
In embedded devices, there's a small, fixed amount of memory to use.
 | 
					In embedded devices, there's a small, fixed amount of memory to use.
 | 
				
			||||||
In a browser, you have no idea how large [google.com](https://www.google.com)'s home page is until you start
 | 
					In a browser, you have no idea how large [google.com](https://www.google.com)'s home page is until you start
 | 
				
			||||||
trying to download it. The compiler uses this information (or lack thereof) to optimize
 | 
					trying to download it. The compiler uses this knowledge (or lack thereof) to optimize
 | 
				
			||||||
how memory is used; put simply, your code runs faster when the compiler can guarantee exactly
 | 
					how memory is used; put simply, your code runs faster when the compiler can guarantee exactly
 | 
				
			||||||
how much memory your program needs while it's running. This post is all about understanding
 | 
					how much memory your program needs while it's running. This series is all about understanding
 | 
				
			||||||
how the compiler reasons about your program, with an emphasis on how to design your programs
 | 
					how the compiler reasons about your program, with an emphasis on the implications for performance.
 | 
				
			||||||
for performance.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Now let's address some conditions and caveats before going much further:
 | 
					Now let's address some conditions and caveats before going much further:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -91,14 +93,14 @@ Now let's address some conditions and caveats before going much further:
 | 
				
			|||||||
  [Compiler Exporer](https://godbolt.org/). As such, we'll avoid upcoming innovations like
 | 
					  [Compiler Exporer](https://godbolt.org/). As such, we'll avoid upcoming innovations like
 | 
				
			||||||
  [compile-time evaluation of `static`](https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md)
 | 
					  [compile-time evaluation of `static`](https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md)
 | 
				
			||||||
  that are available in nightly.
 | 
					  that are available in nightly.
 | 
				
			||||||
- Because of the nature of the content, some (very simple) assembly-level code is involved.
 | 
					- Because of the nature of the content, being able to read assembly is helpful.
 | 
				
			||||||
  We'll keep this simple, but I [found](https://stackoverflow.com/a/4584131/1454178)
 | 
					  We'll keep it simple, but I [found](https://stackoverflow.com/a/4584131/1454178)
 | 
				
			||||||
  a [refresher](https://stackoverflow.com/a/26026278/1454178) on the `push` and `pop`
 | 
					  a [refresher](https://stackoverflow.com/a/26026278/1454178) on the `push` and `pop`
 | 
				
			||||||
  [instructions](http://www.cs.virginia.edu/~evans/cs216/guides/x86.html)
 | 
					  [instructions](http://www.cs.virginia.edu/~evans/cs216/guides/x86.html)
 | 
				
			||||||
  was helpful while writing this post.
 | 
					  was helpful while writing thi[Raph Levien](https://docs.google.com/presentation/d/1q-c7UAyrUlM-eZyTo1pd8SZ0qwA_wYxmPZVOQkoDmH4/edit?usp=sharing)s.
 | 
				
			||||||
- I've tried to be precise in saying only what I can prove using the tools (ASM, docs)
 | 
					- I've tried to be precise in saying only what I can prove using the tools (ASM, docs)
 | 
				
			||||||
  that are available. That said, if there's something said in error, please reach out
 | 
					  that are available, but if there's something said in error it will be corrected
 | 
				
			||||||
  and let me know - [bradlee@speice.io](mailto:bradlee@speice.io)
 | 
					  expeditiously. Please let me know at [bradlee@speice.io](mailto:bradlee@speice.io)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Finally, I'll do what I can to flag potential future changes but the Rust docs
 | 
					Finally, I'll do what I can to flag potential future changes but the Rust docs
 | 
				
			||||||
have a notice worth repeating:
 | 
					have a notice worth repeating:
 | 
				
			||||||
 | 
				
			|||||||
@ -37,9 +37,14 @@ the memory model in Rust:
 | 
				
			|||||||
- `const` is a fixed value; the compiler is allowed to copy it wherever useful.
 | 
					- `const` is a fixed value; the compiler is allowed to copy it wherever useful.
 | 
				
			||||||
- `static` is a fixed reference; the compiler will guarantee it is unique.
 | 
					- `static` is a fixed reference; the compiler will guarantee it is unique.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And a nice visualizaton of the rules, courtesy of
 | 
				
			||||||
 | 
					[Raph Levien](https://docs.google.com/presentation/d/1q-c7UAyrUlM-eZyTo1pd8SZ0qwA_wYxmPZVOQkoDmH4/edit?usp=sharing):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
And if you've read through this series: thanks. I've enjoyed the process that went
 | 
					If you've taken the time to read through this series: thanks. I've enjoyed the
 | 
				
			||||||
into writing this, both in building new tools and forcing myself to understand
 | 
					process that went into writing this, both in building new tools and learning
 | 
				
			||||||
the content well enough to explain it. I hope this is valuable as a reference to you
 | 
					the material well enough to explain it. I hope this is valuable as a reference
 | 
				
			||||||
as well.
 | 
					to you as well.
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 426 KiB After Width: | Height: | Size: 426 KiB  | 
		Reference in New Issue
	
	Block a user