Esta es una publicación antigua, sin embargo, todavía me tomaría la libertad de poner mis pensamientos aquí.
Comenzando desde abajo, Linux primero dividiría la memoria en páginas (generalmente 4K por página en el sistema x86_64). Posteriormente, se crea la memoria virtual, cuyo mapeo se realiza con memoria física utilizando MMU (Unidad de Administración de Memoria).
A los procesos se les asigna memoria desde el área de memoria virtual, así que tenga en cuenta que cuando vea / proc / meminfo, verá VMalloc * como los detalles de la memoria virtual.
Digamos que tiene un proceso que solicita memoria (digamos 300 MB, un navegador web). El proceso se asignaría a 300 MB de la memoria virtual, sin embargo, no es necesario que se asigne a la memoria (que se asigna a la memoria física). Existe el concepto de "Copiar en escritura" para la administración de memoria, según el cual, si sus procesos realmente usan la memoria asignada desde la memoria virtual (es decir, escribe algo en la memoria), solo entonces se asigna a la memoria física. Esto ayuda al kernel a funcionar correctamente en un entorno multiproceso de manera eficiente.
¿Qué son los caché?
Se comparte mucha memoria utilizada por los procesos. Digamos que la biblioteca glibc es utilizada por casi todos los procesos. ¿Cuál es el punto de mantener múltiples copias de glibc en la memoria, cuando cada proceso puede acceder a la misma ubicación de memoria y hacer el trabajo? Dichos recursos de uso frecuente se mantienen en caché para que, cuando los procesos lo exijan, se puedan hacer referencia a la misma ubicación de memoria. Esto ayuda a acelerar los procesos, ya que leer glibc (etc.) una y otra vez desde el disco llevaría mucho tiempo.
Lo anterior fue para bibliotecas compartidas por ejemplo, similar también es cierto para la lectura de archivos también. Si lee un archivo grande (digamos 100-200MB) por primera vez, tomaría mucho tiempo. Sin embargo, cuando intente y vuelva a hacer la misma lectura, sería más rápido. Los datos se almacenaron en la memoria caché y no se volvieron a leer todos los bloques.
¿Qué es el búfer?
En lo que respecta al búfer, cuando un proceso archiva E / S, se basa en el búfer del núcleo para escribir datos en el disco. Los procesos solicitan al núcleo que haga el trabajo. Entonces, en nombre del proceso, el kernel escribe los datos en su "búfer" y le dice al proceso que la escritura ha terminado. De manera asíncrona, el núcleo seguirá sincronizando estos datos en el búfer al disco. De esta forma, los procesos dependen del núcleo para elegir la hora correcta para sincronizar los datos en el disco, y los procesos podrían continuar trabajando en el futuro. Recuerde, esto es E / S general que están haciendo los procesos normales. Sin embargo, los procesos especializados, que necesitan confirmar que la E / S se realiza realmente en el disco, pueden usar otro mecanismo para realizar E / S en el disco. Algunas de las utilidades de código abierto son libaio. Además, hay formas de llamar a la sincronización explícita a los FD abiertos en el contexto de sus procesos,
¿Qué son las fallas de página entonces?
Considere un ejemplo, cuando inicia un proceso (digamos un navegador web), cuyo binario es de aproximadamente 300 MB. Sin embargo, los 300 MB completos del binario del navegador web no comienzan a funcionar instantáneamente. El proceso continúa moviéndose de funciones a funciones en su código. Como se dijo anteriormente, la memoria virtual se consumiría 300 MB, sin embargo, no toda la memoria se asigna a la memoria física (RSS - la memoria residente sería menor, ver salida superior). Cuando la ejecución del código llega a un punto, para el cual la memoria no está realmente mapeada físicamente, se producirá un error de página. Kernel mapearía esta memoria a física, asociaría la página de memoria a su proceso. Este fallo de página se denomina "Fallos de página menores". De manera similar, cuando un proceso está haciendo E / S de archivo, se generan fallas importantes en la página.
¿Cuándo y por qué ocurre el intercambio?
Situación 1:
En línea con los detalles anteriores, consideremos un escenario cuando la buena cantidad de memoria se convierte en memoria asignada. Y ahora se inicia un proceso, que requiere memoria. Como se discutió anteriormente, el núcleo tendrá que hacer un mapeo de memoria. Sin embargo, no hay suficiente RAM física disponible para asignar la memoria. Ahora, el núcleo primero buscará en la memoria caché, tendrá algunas páginas de memoria antiguas que no se están utilizando. Vaciará esas páginas en una partición separada (llamada SWAP), liberará algunas páginas y asignará páginas liberadas a la nueva solicitud que viene. Como la escritura en disco es mucho más lenta que la RAM de estado sólido, este proceso lleva mucho tiempo y, por lo tanto, se observa una desaceleración.
Situación 2:
Digamos que ve mucha memoria libre disponible en el sistema. Incluso entonces ves que está sucediendo mucho intercambio. Podría haber un problema probable de fragmentación de la memoria. Considere un proceso que requiere 50 MB de memoria contigua del núcleo. (tenga en cuenta contiguo). Obviamente, el núcleo habría asignado páginas al azar a diferentes procesos, y habría liberado algunos de ellos. Sin embargo, cuando exigimos memoria contigua, tendrá que buscar un fragmento que satisfaga la demanda de los procesos. Si no puede obtener dicha memoria, tendrá que cambiar algunas páginas de memoria antiguas y luego asignar las contiguas. Incluso en tales casos, sucedería SWAP. Comenzando Kernel ver 2.6 y superior, tales problemas de fragmentación se han reducido considerablemente. Sin embargo, si el sistema se ejecuta durante mucho tiempo, aún podrían surgir tales problemas.
Ver este ejemplo ( salida vmstat )
2016-10-29 03:55:32 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
2016-10-29 03:55:32 r b swpd free buff cache si so bi bo in cs us sy id wa st
2016-10-30 03:56:04 19 23 2914752 4692144 3344908 12162628 1660 1 8803 12701 4336 37487 14 7 40 38 0
2016-10-30 03:56:34 3 20 2889296 4977580 3345316 12026752 2109 2 8445 14665 4656 36294 12 7 46 34 0
2016-10-30 03:57:04 1 11 3418868 4939716 3347804 11536356 586 4744 2547 9535 3086 24450 6 3 59 33 0 <<<-----
2016-10-30 03:57:34 3 19 3456252 5449884 3348400 11489728 3291 13371 6407 17957 2997 22556 6 4 66 24 0
2016-10-30 03:58:04 7 6 4194500 5663580 3349552 10857424 2407 12240 3824 14560 2295 18237 4 2 65 29 0
2016-10-30 03:58:34 2 16 4203036 5986864 3348908 10838492 4601 16639 7219 18808 2575 21563 6 4 60 31 0
2016-10-30 03:59:04 3 14 4205652 6059196 3348760 10821448 6624 1597 9431 4357 1750 20471 6 2 60 31 0
2016-10-30 03:59:34 2 24 4206968 6053160 3348876 10777216 5221 2067 10106 7377 1731 19161 3 3 62 32 0
2016-10-30 04:00:04 0 13 4205172 6005084 3348932 10785896 6236 1609 10330 6264 1739 20348 4 2 67 26 0
2016-10-30 04:00:34 4 11 4206420 5996396 3348976 10770220 6554 1253 10382 4896 1964 42981 10 5 58 27 0
2016-10-30 04:01:04 6 4 4177176 5878852 3348988 10825840 8682 765 10126 2716 1731 32949 8 4 69 19 0
@ 2016-10-30 03:57:04, vemos que todavía hay una buena cantidad de RAM disponible. Sin embargo, incluso entonces sucedió el intercambio. Verificamos el árbol de procesos en este punto, y no vimos ningún proceso que demande tanta cantidad de memoria (más que memoria libre). La sospecha obvia era la situación 2 descrita anteriormente. Verificamos los registros de buddyinfo y zoneinfo arriba (Use echo m> / proc / sysrq-trigger para verificar esto, la salida va a syslogs).
Para un sistema normal nuestro, la comparación de la información de zona va así. Y los gráficos para caché / libre / baja memoria también se mencionan a continuación
Mirando la información, está claro que hay fragmentación de memoria en el nodo 0 y el nodo 1 normal (Nodo, es una máquina basada en NUMA, por lo tanto, múltiples nodos (consulte el numactl para verificar la información de su sistema)).
La fragmentación de la memoria también es una razón por la cual el uso de intercambio puede aumentar incluso cuando hay memoria libre.