pub unsafe trait GlobalAllocator:
Allocator
+ Sync
+ 'static { }allocator_api #32838)Expand description
An Allocator that can be registered as the standard library’s default
through the #[global_allocator] attribute.
Types implementing this trait can be used as the default allocator for
memory allocations through Box, Vec and the collection types. For
instance, the System allocator implements this trait, and thus can be
explicitly set as the default like so:
The Global allocator forwards all memory allocation requests to the
static annotated with #[global_allocator]. Hence, Global does not
implement GlobalAllocator itself, as that would lead to infinite recursion.
§Note to implementors
This trait is used to prevent the infinite recursion that would occur if the
default allocator were to attempt to allocate memory through Global (and
thus from itself).
When to implement this trait:
- for custom global allocators that only use system memory allocation services.
- for allocators that wrap another allocator that implements
GlobalAllocator.
When not to implement this trait:
- for wrappers of arbitrary allocators (which might end up being
Global, leading to infinite recursion).
§Safety
In addition to the safety requirements of Allocator, global allocators are
subject to some additional constraints:
-
It’s undefined behavior if global allocators unwind. This restriction may be lifted in the future, but currently a panic from any of these functions may lead to memory unsafety.
-
You must not rely on allocations actually happening, even if there are explicit heap allocations in the source. The optimizer may detect unused allocations that it can either eliminate entirely or move to the stack and thus never invoke the allocator. The optimizer may further assume that allocation is infallible, so code that used to fail due to allocator failures may now suddenly work because the optimizer worked around the need for an allocation. More concretely, the following code example is unsound, irrespective of whether your custom allocator allows counting how many allocations have happened.
ⓘdrop(Box::new(42)); let number_of_heap_allocs = /* call private allocator API */; unsafe { std::hint::assert_unchecked(number_of_heap_allocs > 0); }Note that the optimizations mentioned above are not the only optimization that can be applied. You may generally not rely on heap allocations happening if they can be removed without changing program behavior. Whether allocations happen or not is not part of the program behavior, even if it could be detected via an allocator that tracks allocations by printing or otherwise having side effects.
§Re-entrance
When implementing a global allocator, one has to be careful not to create an infinitely recursive
implementation by accident, as many constructs in the Rust standard library may allocate in
their implementation. For example, on some platforms, std::sync::Mutex may allocate, so using
it is highly problematic in a global allocator.
For this reason, one should generally stick to library features available through
core, and avoid using std in a global allocator. A few features from std are
guaranteed to not use #[global_allocator] to allocate:
std::thread_local,std::thread::current,std::thread::parkandstd::thread::Thread’sunparkmethod andCloneimplementation.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".