¿Los archivos abiertos por procesos se cargan en la RAM?

¿Los archivos abiertos por procesos se cargan en la RAM?

Comandos, por ejemplo sed, son programas y los programas están codificados lógicamente dentro de un archivo y estos archivos están en algún lugar del disco duro. Sin embargo, cuando se ejecutan comandos, una copia de sus archivos deldisco durose pone en elRAM, donde cobran vida y pueden hacer cosas y se llamanprocesos.

Los procesos pueden hacer uso de otros archivos, leerlos o escribirlos y, si lo hacen, esos archivos se denominan archivos abiertos. Hay un comando para enumerar todos los archivos abiertos por todos los procesos en ejecución: lsof.

Bueno, entonces lo que me pregunto es si la doble vida de un comando, uno en el disco duro y otro en la RAM, también se cumple para otro tipo de archivos, por ejemplo aquellos que no tienen lógica programada, sino que son simplemente contenedores de datos.

Mi suposición es que los archivos abiertos por procesos también se cargan en la RAM. No sé si es cierto, es sólo una intuición.

Por favor, ¿alguien podría entenderlo?

Respuesta1

No, un archivo no se lee automáticamente en la memoria al abrirlo. Eso sería tremendamente ineficiente. sed, por ejemplo, lee su entrada línea por línea, al igual que muchas otras herramientas de Unix. Rara vez es necesario mantener en la memoria más de la línea actual.

Con awkeso es lo mismo. se lee unregistroa la vez, que por defecto es una línea. Si almacena partes de los datos de entrada en variables, eso será adicional, por supuesto 1 .

Algunas personas tienen la costumbre de hacer cosas como

for line in $(cat file); do ...; done

Dado que el shell tendrá que expandir $(cat file)completamente la sustitución de comandos antes de ejecutar incluso la primera iteración del forbucle, estovoluntadlea todo fileen la memoria (en la memoria utilizada por el shell que ejecuta el forbucle). Esto es un poco tonto y además poco elegante. En cambio, uno debería hacer

while IFS= read -r line; do ...; done <file

Esto procesará filelínea por línea (pero leaEntendiendo "IFS= leer -r línea").

Sin embargo, rara vez es necesario procesar archivos línea por línea en el shell, ya que la mayoría de las utilidades están orientadas a líneas de todos modos (consulte¿Por qué se considera una mala práctica utilizar un bucle de shell para procesar texto?).

Estoy trabajando en bioinformática y, al procesar grandes cantidades de datos genómicos, no podría hacer mucho a menos que sólo mantuviera en la memoria los fragmentos de datos que eran absolutamente necesarios. Por ejemplo, cuando necesito eliminar los bits de datos que podrían usarse para identificar individuos de un conjunto de datos de 1 terabyte que contiene variantes de ADN en un archivo VCF (porque ese tipo de datos no se puede hacer público), lo hago línea por línea. procesamiento con un awkprograma simple (esto es posible ya que el formato VCF está orientado a líneas). Inolea el archivo en la memoria, procéselo allí y vuelva a escribirlo. Si el archivo estuviera comprimido, lo pasaría a través de zcato gzip -d -c, que, dado que gzipprocesa datos en flujo, tampoco leería el archivo completo en la memoria.

Incluso con formatos de archivo que sonnoorientados a líneas, como JSON o XML, existen analizadores de flujo que permiten procesar archivos enormes sin almacenarlos todos en la RAM.

Con los ejecutables, es un poco más complicado ya que las bibliotecas compartidas pueden cargarse bajo demanda y/o compartirse entre procesos (consulteCarga de bibliotecas compartidas y uso de RAM., Por ejemplo).

El almacenamiento en caché es algo que no he mencionado aquí. Esta es la acción de usar RAM para almacenar datos a los que se accede con frecuencia. El sistema operativo puede almacenar en caché archivos más pequeños (por ejemplo, ejecutables) con la esperanza de que el usuario haga muchas referencias a ellos. Aparte de la primera lectura del fichero, los accesos posteriores se realizarán a la RAM y no al disco. El almacenamiento en caché, como el almacenamiento en búfer de entrada y salida, suele ser en gran medida transparente para el usuario y la cantidad de memoria utilizada para almacenar en caché las cosas puede cambiar dinámicamente dependiendo de la cantidad de RAM asignada por las aplicaciones, etc.


1 Técnicamente, la mayoría de los programas probablemente leen un fragmento de los datos de entrada a la vez, ya sea usando el almacenamiento en búfer explícito o implícitamente a través del almacenamiento en búfer que hacen las bibliotecas de E/S estándar, y luego presentan ese fragmento línea por línea al código del usuario. Es mucho más eficiente leer un múltiplo del tamaño de bloque del disco que, por ejemplo, un carácter a la vez. Sin embargo, este tamaño de fragmento rara vez será mayor que un puñado de kilobytes.

Respuesta2

Sin embargo, cuando se ejecutan comandos, una copia de sus archivos del disco duro se coloca en la RAM,

Esto está mal (en general). Cuando se ejecuta un programa (a través deejecutivo(2)...) el proceso (que ejecuta ese programa) está cambiando suespacio de direcciones virtualesy el kernel está reconfigurando elMMUpara ese propósito. Lea también sobrememoria virtual. Tenga en cuenta que los programas de aplicación pueden cambiar su espacio de direcciones virtuales usandomapamm(2)& munmap&proteger(2), también utilizado por elenlazador dinámico(verld-linux(8)). Ver tambiénmadvis(2)&posix_fadvise(2)&bloqueo(2).

Futurofallas de paginaserá procesado por el kernel para cargar (perezosamente) páginas desde el archivo ejecutable. Lea también sobrepaliza.

El núcleo mantiene una grancaché de página. Lea también sobreCopiar en escrito. Ver tambiénlectura anticipada(2).

Bueno, entonces lo que me pregunto es si la doble vida de un comando, uno en el disco duro y otro en la RAM, también se cumple para otro tipo de archivos, por ejemplo aquellos que no tienen lógica programada, sino que son simplemente contenedores de datos.

Parallamadas al sistemacomoleer(2)&escribir(2)También se utiliza el caché de la página. Si los datos a leer se encuentran en él, no se realizará ninguna E/S del disco. Si se necesita E/S de disco, es muy probable que los datos leídos se guarden en la memoria caché de la página. Entonces, en la práctica, si ejecuta el mismo comando dos veces, podría suceder que no se realice ninguna E/S física en el disco la segunda vez (si tiene un disco duro giratorio antiguo, no un SSD, es posible que escuche eso; u observe atentamente el LED de su disco duro).

Recomiendo leer un libro comoSistemas operativos: tres piezas sencillas(descargable gratuitamente, un archivo PDF por capítulo) que explica todo esto.

Ver tambiénLinux se comió mi RAMy ejecute comandos como xosview, topo htopo cat /proc/self/maps( cat /proc/$$/mapsconsulteproceso(5)).

PD. Me estoy centrando en Linux, pero otros sistemas operativos también tienen memoria virtual y caché de páginas.

Respuesta3

No. Si bien tener gigas de RAM hoy en día es fantástico, hubo un tiempo en el que la RAM era un recurso muy limitado (aprendí a programar en un VAX 11/750 con 2 MB de RAM) y lo único que había en la RAM eran archivos ejecutables activos y páginas de datos. de procesos activos y datos de archivos que estaban en la memoria caché del búfer.
Se vació la memoria caché del búfer y se intercambiaron las páginas de datos. Y frecuentemente a veces. Las páginas ejecutables de solo lectura se sobrescribieron y las tablas de páginas se marcaron, de modo que si el programa tocaba esas páginas nuevamente, se paginaban desde el sistema de archivos. Los datos fueron ingresados ​​desde el intercambio. Como se señaló anteriormente, la biblioteca STDIO extraía datos en bloques y el programa los obtenía según fuera necesario: fgetc, fgets, fread, etc. Con mmap, un archivo se podía asignar al espacio de direcciones de un proceso, como se hace con objetos de biblioteca compartidos o incluso archivos normales. Sí, es posible que tenga cierto grado de control si está en la RAM o no (mlock), pero solo llega hasta cierto punto (consulte la sección de códigos de error de mlock).

información relacionada