En Rust, el asignador es responsable de la asignación y liberación de memoria dinámica (heap). Por defecto, Rust utiliza el asignador del sistema estándar, pero el lenguaje ofrece la posibilidad de usar asignadores personalizados a través de interfaces globales y locales. Esto es necesario para:
Desde la versión 1.28, el asignador global se define a través del atributo #[global_allocator]:
use std::alloc::System; #[global_allocator] static GLOBAL: System = System;
Se puede crear un asignador propio implementando los traits de std::alloc:
use std::alloc::{GlobalAlloc, Layout}; struct MyAlloc; unsafe impl GlobalAlloc for MyAlloc { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { // Aquí la lógica de asignación std::alloc::System.alloc(layout) // delegamos } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { // Lógica de liberación std::alloc::System.dealloc(ptr, layout) } } #[global_allocator] static GLOBAL: MyAlloc = MyAlloc;
Pregunta: ¿Se puede cambiar el asignador global en tiempo de ejecución, por ejemplo, dependiendo de condiciones o configuraciones?
Respuesta: ¡No! El asignador global se elige en tiempo de compilación y se establece de forma estática a través de #[global_allocator]. No se puede cambiar en tiempo de ejecución o seleccionar dinámicamente, ya que este atributo afecta al código generado durante la compilación.
Historia
Box::new. La implementación de un asignador propio con acceso a grupos de memoria estáticos ayudó.Historia
Historia
Al desarrollar una aplicación de escritorio se utilizó un asignador externo jemalloc, sin tener en cuenta la diferencia de ABI entre las versiones de rustc. Esto llevó a fallos difíciles de detectar durante la serialización de datos, ya que diferentes partes del código esperaban diferentes convenciones de asignación de memoria.