Skip to content

Commit 9c24c62

Browse files
committed
Merge pull request #4440 from pcwalton/tutorial
doc: Fold information from the memory model interlude in the tutorial elsewhere
2 parents 989667e + f0fa67d commit 9c24c62

File tree

1 file changed

+51
-9
lines changed

1 file changed

+51
-9
lines changed

doc/tutorial.md

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -863,11 +863,34 @@ allocating memory and indirecting through a pointer. But for big structs, or
863863
those with mutable fields, it can be useful to have a single copy on
864864
the stack or on the heap, and refer to that through a pointer.
865865

866-
Rust supports several types of pointers. The safe pointer types are
867-
`@T`, for managed boxes allocated on the local heap, `~T`, for
868-
uniquely-owned boxes allocated on the exchange heap, and `&T`, for
869-
borrowed pointers, which may point to any memory, and whose lifetimes
870-
are governed by the call stack.
866+
Whenever memory is allocated on the heap, the program needs a strategy to
867+
dispose of the memory when no longer needed. Most languages, such as Java or
868+
Python, use *garbage collection* for this, a strategy in which the program
869+
periodically searches for allocations that are no longer reachable in order
870+
to dispose of them. Other languages, such as C, use *manual memory
871+
management*, which relies on the programmer to specify when memory should be
872+
reclaimed.
873+
874+
Rust is in a different position. It differs from the garbage-collected
875+
environments in that allows the programmer to choose the disposal
876+
strategy on an object-by-object basis. Not only does this have benefits for
877+
performance, but we will later see that this model has benefits for
878+
concurrency as well, by making it possible for the Rust compiler to detect
879+
data races at compile time. Rust also differs from the manually managed
880+
languages in that it is *safe*—it uses a [pointer lifetime
881+
analysis][borrow] to ensure that manual memory management cannot cause memory
882+
errors at runtime.
883+
884+
[borrow]: tutorial-borrowed-ptr.html
885+
886+
The cornerstone of Rust's memory management is the concept of a *smart
887+
pointer*—a pointer type that indicates the lifetime of the object it points
888+
to. This solution is familiar to C++ programmers; Rust differs from C++,
889+
however, in that a small set of smart pointers are built into the language.
890+
The safe pointer types are `@T`, for *managed* boxes allocated on the *local
891+
heap*, `~T`, for *uniquely-owned* boxes allocated on the *exchange
892+
heap*, and `&T`, for *borrowed* pointers, which may point to any memory, and
893+
whose lifetimes are governed by the call stack.
871894

872895
All pointer types can be dereferenced with the `*` unary operator.
873896

@@ -919,7 +942,17 @@ node2.next = SomeNode(node3);
919942
node3.prev = SomeNode(node2);
920943
~~~
921944

922-
Managed boxes never cross task boundaries.
945+
Managed boxes never cross task boundaries. This has several benefits for
946+
performance:
947+
948+
* The Rust garbage collector does not need to stop multiple threads in order
949+
to collect garbage.
950+
951+
* You can separate your application into "real-time" tasks that do not use
952+
the garbage collector and "non-real-time" tasks that do, and the real-time
953+
tasks will not be interrupted by the non-real-time tasks.
954+
955+
C++ programmers will recognize `@T` as similar to `std::shared_ptr<T>`.
923956

924957
> ***Note:*** Currently, the Rust compiler generates code to reclaim
925958
> managed boxes through reference counting and a cycle collector, but
@@ -956,10 +989,19 @@ let z = *x + *y;
956989
assert z == 20;
957990
~~~~
958991

959-
Owned boxes, when they do not contain any managed boxes, can be sent
960-
to other tasks. The sending task will give up ownership of the box,
992+
When they do not contain any managed boxes, owned boxes can be sent
993+
to other tasks. The sending task will give up ownership of the box
961994
and won't be able to access it afterwards. The receiving task will
962-
become the sole owner of the box.
995+
become the sole owner of the box. This prevents *data races*—errors
996+
that could otherwise result from multiple tasks working on the same
997+
data without synchronization.
998+
999+
When an owned pointer goes out of scope or is overwritten, the object
1000+
it points to is immediately freed. Effective use of owned boxes can
1001+
therefore be an efficient alternative to garbage collection.
1002+
1003+
C++ programmers will recognize `~T` as similar to `std::unique_ptr<T>`
1004+
(or `std::auto_ptr<T>` in C++03 and below).
9631005

9641006
## Borrowed pointers
9651007

0 commit comments

Comments
 (0)