GNU/Linux >> Tutoriales Linux >  >> Linux

mmap:¿el archivo mapeado se cargará en la memoria inmediatamente?

Sí, mmap crea un mapeo. Normalmente no lee todo el contenido de lo que hayas mapeado en la memoria. Si desea hacer eso, puede usar la llamada al sistema mlock/mlockall para obligar al kernel a leer en la RAM el contenido de la asignación, si corresponde.


No, sí, tal vez. Depende.

Llamando a mmap generalmente solo significa que para su aplicación, el contenido del archivo asignado se asigna a su espacio de direcciones como si el archivo fue cargado allí. O, como si el archivo realmente existiera en la memoria, como si fueran uno y el mismo (lo que incluye los cambios que se vuelven a escribir en el disco, suponiendo que tenga acceso de escritura).

Ni mas ni menos. No tiene noción de cargar algo, ni la aplicación sabe lo que esto significa.

Una aplicación realmente no tiene conocimiento de algo como la memoria, aunque el sistema de memoria virtual lo hace parecer así. La memoria que una aplicación puede "ver" (y acceder) puede corresponder o no a la memoria física real y, en principio, puede cambiar en cualquier momento, sin previo aviso y sin una razón obvia (obvia para su aplicación).
Además de experimentar un pequeño retraso debido a una falla en la página, una aplicación (en principio) no es consciente de que tal cosa suceda y tiene poco o ningún control sobre ello.

Las aplicaciones, por lo general, cargarán páginas de archivos mapeados (¡incluido el ejecutable principal!) a pedido, como consecuencia de encontrar una falla. Sin embargo, un sistema operativo generalmente intentará obtener datos de forma especulativa para optimizar el rendimiento.

En la práctica, llamar a mmap inmediatamente comenzará para precargar (asincrónicamente) páginas desde el comienzo del mapeo, hasta un cierto tamaño especificado por la implementación. Lo que significa que, en principio, para archivos pequeños la respuesta sería "sí", y para archivos más grandes sería "no".
Sin embargo, mmap no se bloquea para esperar a que se complete la lectura anticipada, lo que significa que no tiene garantía de que alguno de los archivos esté en la RAM inmediatamente después de mmap devoluciones (no es que usted tenga esa garantía en cualquier momento de todos modos!). En la medida en que la respuesta es "tal vez".

En Linux, la última vez que miré, el tamaño predeterminado de captación previa era de 31 bloques (~127k), pero esto puede haber cambiado, además es un parámetro ajustable. A medida que se tocan las páginas cercanas o al final del área precargada, más páginas se precargan de forma asincrónica.
Si has insinuado MADV_RANDOM a madvise , la captación previa es "menos probable que suceda", en Linux esto desactiva completamente la captación previa.

Por otro lado, dando el MADV_SEQUENTIAL La sugerencia precargará de forma asíncrona "más agresivamente" desde el principio del mapeo (y puede descartar las páginas a las que se accede más rápido). Bajo Linux, "más agresivamente" significa el doble de la cantidad normal.

Dando el MADV_WILLNEED la sugerencia sugiere (pero no garantiza) que todas las páginas en el rango dado se carguen lo antes posible (ya que está diciendo que va a acceder a ellas). El sistema operativo puede ignorar esto, pero en Linux, se trata más como una orden que como una pista, hasta el límite máximo de RSS del proceso y un límite especificado por la implementación (si no recuerdo mal, la mitad de la cantidad de RAM física ).
Tenga en cuenta que MADV_DONTNEED podría decirse que está mal implementado en Linux. La sugerencia no se interpreta de la manera especificada por POSIX, es decir, está de acuerdo con que las páginas se descarguen por el momento, sino que quiere descartarlas . Lo que no hace una gran diferencia para las páginas asignadas de solo lectura (aparte de un pequeño retraso, que dijiste que estaría bien), pero seguro que sí importa para todo lo demás
En particular, usando MADV_DONTNEED pensar que Linux liberará páginas innecesarias después de que el sistema operativo las haya escrito perezosamente en el disco no es así como funcionan las cosas ! Debes sincronizar explícitamente o prepararte para una sorpresa.

Habiendo llamado readahead en el descriptor de archivo antes de llamar a mmap (o alternativamente, habiendo leído/escrito el archivo previamente), el contenido del archivo en la práctica de hecho estar en RAM inmediatamente.
Sin embargo, esto es solo un detalle de implementación (sistema de memoria virtual unificado) y está sujeto a la presión de la memoria en el sistema.

Llamando al mlock -suponiendo que tenga éxito- cargará inmediatamente las páginas solicitadas en la RAM. Bloquea hasta que todas las páginas están físicamente presentes y tiene la garantía de que las páginas permanecerán en la RAM hasta que las desbloquee.

Existe funcionalidad para consultar (mincore ) si alguna o todas las páginas en un rango particular están realmente presentes en ese momento, y la funcionalidad para indicarle al sistema operativo lo que le gustaría ver que suceda sin garantías concretas (madvise ), y finalmente la funcionalidad para forzar la presencia de un subconjunto limitado de páginas en la memoria (mlock ) para procesos privilegiados.

Puede que no, tanto por falta de privilegios como por exceder las cuotas o la cantidad de memoria RAM física presente.


De forma predeterminada, mmap() solo configura el mapeo y los retornos (rápido).

Linux (al menos) tiene la opción MAP_POPULATE (ver 'man mmap') que hace exactamente de lo que trata tu pregunta.


Linux
  1. ¿Cuál es la diferencia entre escribir en un archivo y una memoria mapeada?

  2. Gato recursivo todos los archivos en un solo archivo

  3. Linux:'Nombre de usuario' no está en el archivo sudoers. Este incidente será reportado

  4. ¿Se carga todo el núcleo en la memoria al arrancar?

  5. ¿Cómo puedo obtener la cantidad de memoria disponible de forma portátil entre distribuciones?

¿Está Mv Atomic en el Fs?

¿Insertar un archivo en otro archivo después de la primera aparición de un patrón?

Salida a Stdout y al mismo tiempo Grep en un archivo?

¿Copiar el contenido de un archivo en el portapapeles sin mostrar su contenido?

Si cambio los permisos en un archivo Tar, ¿se aplicará eso a los archivos que contiene?

Cómo hacer eco en un archivo