Move Unstable Book sections for #[global_allocator] and System to std::alloc docs
This commit is contained in:
parent
fd6e08a1e6
commit
a24924f683
4 changed files with 85 additions and 148 deletions
|
@ -1,72 +0,0 @@
|
|||
# `global_allocator`
|
||||
|
||||
The tracking issue for this feature is: [#27389]
|
||||
|
||||
[#27389]: https://github.com/rust-lang/rust/issues/27389
|
||||
|
||||
------------------------
|
||||
|
||||
Rust programs may need to change the allocator that they're running with from
|
||||
time to time. This use case is distinct from an allocator-per-collection (e.g. a
|
||||
`Vec` with a custom allocator) and instead is more related to changing the
|
||||
global default allocator, e.g. what `Vec<T>` uses by default.
|
||||
|
||||
Currently Rust programs don't have a specified global allocator. The compiler
|
||||
may link to a version of [jemalloc] on some platforms, but this is not
|
||||
guaranteed. Libraries, however, like cdylibs and staticlibs are guaranteed
|
||||
to use the "system allocator" which means something like `malloc` on Unixes and
|
||||
`HeapAlloc` on Windows.
|
||||
|
||||
[jemalloc]: https://github.com/jemalloc/jemalloc
|
||||
|
||||
The `#[global_allocator]` attribute, however, allows configuring this choice.
|
||||
You can use this to implement a completely custom global allocator to route all
|
||||
default allocation requests to a custom object. Defined in [RFC 1974] usage
|
||||
looks like:
|
||||
|
||||
[RFC 1974]: https://github.com/rust-lang/rfcs/pull/1974
|
||||
|
||||
```rust
|
||||
#![feature(global_allocator, allocator_api, heap_api)]
|
||||
|
||||
use std::alloc::{GlobalAlloc, System, Layout};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
struct MyAllocator;
|
||||
|
||||
unsafe impl GlobalAlloc for MyAllocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
System.alloc(layout)
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
System.dealloc(ptr, layout)
|
||||
}
|
||||
}
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: MyAllocator = MyAllocator;
|
||||
|
||||
fn main() {
|
||||
// This `Vec` will allocate memory through `GLOBAL` above
|
||||
let mut v = Vec::new();
|
||||
v.push(1);
|
||||
}
|
||||
```
|
||||
|
||||
And that's it! The `#[global_allocator]` attribute is applied to a `static`
|
||||
which implements the `Alloc` trait in the `std::alloc` module. Note, though,
|
||||
that the implementation is defined for `&MyAllocator`, not just `MyAllocator`.
|
||||
You may wish, however, to also provide `Alloc for MyAllocator` for other use
|
||||
cases.
|
||||
|
||||
A crate can only have one instance of `#[global_allocator]` and this instance
|
||||
may be loaded through a dependency. For example `#[global_allocator]` above
|
||||
could have been placed in one of the dependencies loaded through `extern crate`.
|
||||
|
||||
Note that `Alloc` itself is an `unsafe` trait, with much documentation on the
|
||||
trait itself about usage and for implementors. Extra care should be taken when
|
||||
implementing a global allocator as well as the allocator may be called from many
|
||||
portions of the standard library, such as the panicking routine. As a result it
|
||||
is highly recommended to not panic during allocation and work in as many
|
||||
situations with as few dependencies as possible as well.
|
|
@ -1,76 +0,0 @@
|
|||
# `alloc_system`
|
||||
|
||||
The tracking issue for this feature is: [#32838]
|
||||
|
||||
[#32838]: https://github.com/rust-lang/rust/issues/32838
|
||||
|
||||
See also [`global_allocator`](language-features/global-allocator.html).
|
||||
|
||||
------------------------
|
||||
|
||||
The compiler currently ships two default allocators: `alloc_system` and
|
||||
`alloc_jemalloc` (some targets don't have jemalloc, however). These allocators
|
||||
are normal Rust crates and contain an implementation of the routines to
|
||||
allocate and deallocate memory. The standard library is not compiled assuming
|
||||
either one, and the compiler will decide which allocator is in use at
|
||||
compile-time depending on the type of output artifact being produced.
|
||||
|
||||
Binaries generated by the compiler will use `alloc_jemalloc` by default (where
|
||||
available). In this situation the compiler "controls the world" in the sense of
|
||||
it has power over the final link. Primarily this means that the allocator
|
||||
decision can be left up the compiler.
|
||||
|
||||
Dynamic and static libraries, however, will use `alloc_system` by default. Here
|
||||
Rust is typically a 'guest' in another application or another world where it
|
||||
cannot authoritatively decide what allocator is in use. As a result it resorts
|
||||
back to the standard APIs (e.g. `malloc` and `free`) for acquiring and releasing
|
||||
memory.
|
||||
|
||||
# Switching Allocators
|
||||
|
||||
Although the compiler's default choices may work most of the time, it's often
|
||||
necessary to tweak certain aspects. Overriding the compiler's decision about
|
||||
which allocator is in use is done through the `#[global_allocator]` attribute:
|
||||
|
||||
```rust,no_run
|
||||
#![feature(alloc_system, global_allocator, allocator_api)]
|
||||
|
||||
extern crate alloc_system;
|
||||
|
||||
use alloc_system::System;
|
||||
|
||||
#[global_allocator]
|
||||
static A: System = System;
|
||||
|
||||
fn main() {
|
||||
let a = Box::new(4); // Allocates from the system allocator.
|
||||
println!("{}", a);
|
||||
}
|
||||
```
|
||||
|
||||
In this example the binary generated will not link to jemalloc by default but
|
||||
instead use the system allocator. Conversely to generate a dynamic library which
|
||||
uses jemalloc by default one would write:
|
||||
|
||||
(The `alloc_jemalloc` crate cannot be used to control the global allocator,
|
||||
crate.io’s `jemallocator` crate provides equivalent functionality.)
|
||||
|
||||
```toml
|
||||
# Cargo.toml
|
||||
[dependencies]
|
||||
jemallocator = "0.1"
|
||||
```
|
||||
```rust,ignore
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
extern crate jemallocator;
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
||||
|
||||
pub fn foo() {
|
||||
let a = Box::new(4); // Allocates from jemalloc.
|
||||
println!("{}", a);
|
||||
}
|
||||
# fn main() {}
|
||||
```
|
|
@ -44,6 +44,29 @@ use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout};
|
|||
use core::ptr::NonNull;
|
||||
|
||||
/// The default memory allocator provided by the operating system.
|
||||
///
|
||||
/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
|
||||
/// plus related functions.
|
||||
///
|
||||
/// This type can be used in a `static` item
|
||||
/// with the `#[global_allocator]` attribute
|
||||
/// to force the global allocator to be the system’s one.
|
||||
/// (The default is jemalloc for executables, on some platforms.)
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::alloc::System;
|
||||
///
|
||||
/// #[global_allocator]
|
||||
/// static A: System = System;
|
||||
///
|
||||
/// fn main() {
|
||||
/// let a = Box::new(4); // Allocates from the system allocator.
|
||||
/// println!("{}", a);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// It can also be used directly to allocate memory
|
||||
/// independently of the standard library’s global allocator.
|
||||
#[stable(feature = "alloc_system_type", since = "1.28.0")]
|
||||
pub struct System;
|
||||
|
||||
|
|
|
@ -9,6 +9,68 @@
|
|||
// except according to those terms.
|
||||
|
||||
//! Memory allocation APIs
|
||||
//!
|
||||
//! In a given program, the standard library has one “global” memory allocator
|
||||
//! that is used for example by `Box<T>` and `Vec<T>`.
|
||||
//!
|
||||
//! Currently the default global allocator is unspecified.
|
||||
//! The compiler may link to a version of [jemalloc] on some platforms,
|
||||
//! but this is not guaranteed.
|
||||
//! Libraries, however, like `cdylib`s and `staticlib`s are guaranteed
|
||||
//! to use the [`System`] by default.
|
||||
//!
|
||||
//! [jemalloc]: https://github.com/jemalloc/jemalloc
|
||||
//! [`System`]: struct.System.html
|
||||
//!
|
||||
//! # The `#[global_allocator]` attribute
|
||||
//!
|
||||
//! This attribute allows configuring the choice of global allocator.
|
||||
//! You can use this to implement a completely custom global allocator
|
||||
//! to route all default allocation requests to a custom object.
|
||||
//!
|
||||
//! ```rust
|
||||
//! use std::alloc::{GlobalAlloc, System, Layout};
|
||||
//!
|
||||
//! struct MyAllocator;
|
||||
//!
|
||||
//! unsafe impl GlobalAlloc for MyAllocator {
|
||||
//! unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
//! System.alloc(layout)
|
||||
//! }
|
||||
//!
|
||||
//! unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
//! System.dealloc(ptr, layout)
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! #[global_allocator]
|
||||
//! static GLOBAL: MyAllocator = MyAllocator;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // This `Vec` will allocate memory through `GLOBAL` above
|
||||
//! let mut v = Vec::new();
|
||||
//! v.push(1);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! The attribute is used on a `static` item whose type implements the
|
||||
//! [`GlobalAlloc`] trait. This type can be provided by an external library:
|
||||
//!
|
||||
//! [`GlobalAlloc`]: ../../core/alloc/trait.GlobalAlloc.html
|
||||
//!
|
||||
//! ```rust,ignore (demonstrates crates.io usage)
|
||||
//! extern crate jemallocator;
|
||||
//!
|
||||
//! use jemallacator::Jemalloc;
|
||||
//!
|
||||
//! #[global_allocator]
|
||||
//! static GLOBAL: Jemalloc = Jemalloc;
|
||||
//!
|
||||
//! fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! The `#[global_allocator]` can only be used once in a crate
|
||||
//! or its recursive dependencies.
|
||||
|
||||
#![stable(feature = "alloc_module", since = "1.28.0")]
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue