Los Memory-mapped files (archivos mapeados en memoria) son una técnica de gestión de memoria que permite a un programa acceder al contenido de un archivo en disco como si fuera una región de memoria RAM. En lugar de realizar operaciones explícitas de lectura/escritura a través de llamadas al sistema (como `read()` o `write()`), el sistema operativo mapea el archivo (o una parte de él) directamente en el espacio de direcciones virtuales del proceso. Esto significa que cualquier acceso a esa región de memoria virtual se traduce automáticamente en operaciones de lectura o escritura en el archivo subyacente, gestionadas por el subsistema de memoria virtual del kernel. El sistema operativo se encarga de cargar las páginas del archivo en memoria física bajo demanda (on-demand paging) y de escribir las modificaciones de vuelta al disco (dirty pages) de forma asíncrona, optimizando el I/O.
Esta técnica es fundamental en numerosos sistemas y herramientas de alto rendimiento. Bases de datos como MongoDB y algunas implementaciones de sistemas de archivos (ej. ext4, XFS para ciertos metadatos o journaling) utilizan Memory-mapped files para gestionar el almacenamiento persistente de forma eficiente. Los sistemas de mensajería de alto rendimiento como Apache Kafka y Apache ActiveMQ Artemis los emplean para sus logs de mensajes, permitiendo un throughput elevado y baja latencia al evitar copias de datos entre el kernel y el espacio de usuario. En el ámbito de la programación, bibliotecas como RocksDB o LMDB (Lightning Memory-Mapped Database) son ejemplos claros de cómo esta técnica se utiliza para construir bases de datos embebidas extremadamente rápidas. Además, son comúnmente usados para la comunicación entre procesos (IPC) compartiendo una región de memoria mapeada al mismo archivo.
Para un arquitecto de sistemas, comprender los Memory-mapped files es crucial por varias razones estratégicas. Ofrecen una forma de I/O de archivos extremadamente eficiente, reduciendo la sobrecarga de las llamadas al sistema y las copias de datos (zero-copy I/O) entre el kernel y el espacio de usuario. Esto se traduce en un mayor rendimiento y menor latencia para aplicaciones intensivas en I/O. Sin embargo, su uso introduce trade-offs importantes: la gestión de errores (ej. errores de disco) puede ser más compleja, ya que se manifiestan como fallos de página (page faults) en lugar de errores explícitos de I/O. La consistencia de los datos y la sincronización con el disco (`fsync()`) deben gestionarse cuidadosamente para evitar pérdida de datos en caso de fallos del sistema. Además, el tamaño del archivo mapeado puede consumir una parte significativa del espacio de direcciones virtuales del proceso, lo que puede ser una consideración en sistemas de 32 bits o con muchas regiones mapeadas. Un arquitecto debe evaluar si los beneficios de rendimiento superan la complejidad adicional en la gestión de errores y la necesidad de una sincronización explícita.