GNU/Linux >> Tutoriales Linux >  >> Linux

Linux:¿Linux realiza un "intercambio oportunista" o es un Theth?

Supongamos que un programa solicita algo de memoria, pero no queda suficiente memoria libre. Hay varias formas diferentes en que Linux podría responder. Una respuesta es seleccionar alguna otra memoria usada, a la que no se haya accedido recientemente, y mover esta memoria inactiva para intercambiar.

Sin embargo, veo muchos artículos y comentarios que van más allá de esto. Dicen que incluso cuando hay una gran cantidad de memoria libre, Linux a veces decide escribir memoria inactiva para intercambiar. Escribir para intercambiar por adelantado significa que cuando finalmente queramos usar esta memoria, no tenemos que esperar a que se escriba en el disco. Dicen que esta es una estrategia deliberada para optimizar el rendimiento.

¿Tienen razón? ¿O es un mito? Cita tu(s) fuente(s).

Por favor, comprenda esta pregunta usando las siguientes definiciones:

  • intercambiar
  • gratis memoria:la memoria "libre" mostrada por el comando libre. Este es el MemFree valor de /proc/meminfo . /proc/meminfo es un archivo de texto virtual proporcionado por el kernel. Consulte proc(5) o documentos de RHEL.
  • incluso cuando hay una gran cantidad de memoria libre – a los efectos del argumento, imagine que hay más del 10 % de memoria libre.

Referencias

Aquí hay algunos términos de búsqueda:linux "intercambio oportunista" O (intercambio "cuando el sistema no tiene nada mejor que hacer" O "cuando no tiene nada mejor que hacer" O "cuando el sistema está inactivo" O "durante el tiempo de inactividad")

En el segundo resultado más alto en Google, un usuario de StackExchange pregunta "¿Por qué usar el intercambio cuando hay espacio libre más que suficiente en la RAM?" y copia los resultados de free Comando que muestra aproximadamente un 20% de memoria libre. En respuesta a esta pregunta específica, veo que esta respuesta es altamente votada:

Linux comienza a intercambiar antes de que se llene la RAM. Esto se hace para
mejorar el rendimiento y la capacidad de respuesta:

  • El rendimiento aumenta porque, a veces, la memoria RAM se usa mejor para la memoria caché del disco que para almacenar la memoria del programa. Por lo tanto, es mejor cambiar un programa
    que ha estado inactivo durante un tiempo y, en su lugar, mantener los archivos
    de uso frecuente en caché.

  • La capacidad de respuesta se mejora intercambiando páginas cuando el sistema está inactivo, en lugar de cuando la memoria está llena y algún programa se está ejecutando
    y solicita más RAM para completar una tarea.

El intercambio ralentiza el sistema, por supuesto, pero la alternativa al
intercambio no es no intercambiar, es tener más RAM o usar menos RAM.

El primer resultado en Google ha sido marcado como un duplicado de la pregunta anterior :-). En este caso, el autor de la pregunta copió los detalles que mostraban 7 GB MemFree , de 16 GB. La pregunta tiene su propia respuesta aceptada y votada:

Intercambiar solo cuando no hay memoria libre solo es el caso si configura swappiness a 0. De lo contrario, durante el tiempo de inactividad, el núcleo intercambiará memoria. Al hacer esto, los datos no se eliminan de la memoria, sino que se realiza una copia en la partición de intercambio.

Esto significa que, si surge la situación de que la memoria se agota, no tiene que escribir en el disco en ese momento. En este caso, el núcleo puede simplemente sobrescribir las páginas de memoria que ya han sido intercambiadas, por lo que sabe que tiene una copia de los datos.

El swappiness el parámetro básicamente solo controla cuánto hace esto.

La otra cita no afirma explícitamente que los datos intercambiados también se retengan en la memoria. Pero parece que preferiría ese enfoque, si está intercambiando incluso cuando tiene un 20 % de memoria libre, y la razón por la que lo hace es para mejorar el rendimiento.

Hasta donde yo sé, Linux admite mantener una copia de los mismos datos tanto en la memoria principal como en el espacio de intercambio.

También noté la afirmación común de que el "intercambio oportunista" ocurre "durante el tiempo de inactividad". Entiendo que se supone que debe ayudarme a asegurarme de que esta característica es generalmente buena para el rendimiento. No incluyo esto en mi definición anterior, porque creo que ya tiene suficientes detalles para hacer una buena pregunta clara. No quiero hacer esto más complicado de lo necesario.

Motivación original

arriba muestra `swout` (intercambio) cuando tengo gigabytes de memoria libre. ¿Por qué?

Hay un par de informes como este, de Linux escribiendo para intercambiar cuando hay mucha memoria libre. El "intercambio oportunista" podría explicar estos informes. Al mismo tiempo, se sugirió al menos una causa alternativa. Como primer paso para buscar posibles causas:¿Linux alguna vez realiza "intercambios oportunistas" como se definió anteriormente?

En el ejemplo que informé, la pregunta ahora ha sido respondida. La causa no fue un intercambio oportunista.

Respuesta aceptada:

Linux no realiza "intercambios oportunistas" como se define en esta pregunta.

Las siguientes referencias principales no mencionan el concepto en absoluto:

  1. Comprensión del administrador de memoria virtual de Linux. Un libro en línea de Mel Gorman. Escrito en 2003, justo antes del lanzamiento de Linux 2.6.0.
  2. Documentación/admin-guide/sysctl/vm.rst. Esta es la documentación principal de la configuración ajustable de la administración de memoria virtual de Linux.
Relacionado:¿Redirigir STDERR y STDOUT a diferentes variables sin archivos temporales?

Más específicamente:

10.6 Demonio de salida de página (kswapd)

Históricamente kswapd Solía ​​activarse cada 10 segundos, pero ahora solo lo activa el asignador de páginas físicas cuando se alcanza el número de páginas libres en una zona. […] Bajo una presión de memoria extrema, los procesos harán el trabajo de kswapd sincrónicamente […] kswapd continúa liberando páginas hasta que se alcanza la marca de agua pages_high.

Según lo anterior, no esperaríamos ningún intercambio cuando el número de páginas gratuitas sea mayor que la "marca de agua máxima".

En segundo lugar, esto nos dice el propósito de kswapd es hacer más páginas gratuitas.

Cuando kswapd escribe una página de memoria para intercambiar, inmediatamente libera la página de memoria. kswapd no guarda una copia de la página intercambiada en la memoria .

Linux 2.6 usa el “rmap” para liberar la página. En Linux 2.4, la historia era más compleja. Cuando varios procesos compartían una página, kswapd no podía liberarla inmediatamente. Esta es la historia antigua. Todas las publicaciones vinculadas son sobre Linux 2.6 o superior.

intercambio

Este control se utiliza para definir la agresividad con la que el kernel intercambiará
páginas de memoria. Los valores más altos aumentarán la agresividad, los valores más bajos
disminuirán la cantidad de intercambio. Un valor de 0 le indica al kernel que no
inicie el intercambio hasta que se agote la cantidad de páginas libres y respaldadas por archivos. es menor
que la marca de agua más alta en una zona.

Esta cita describe un caso especial:si configura el swappiness valor para ser . En este caso, tampoco deberíamos esperar ningún intercambio hasta que el número de páginas de caché haya caído al límite máximo. En otras palabras, el kernel intentará descartar casi todo el caché de archivos antes de comenzar a intercambiar. (Esto podría causar ralentizaciones masivas. ¡Necesitas tener un caché de archivos! El caché de archivos se usa para almacenar el código de todos tus programas en ejecución 🙂

¿Qué son las marcas de agua?

Las citas anteriores plantean la pregunta:¿Qué tan grandes son las reservas de memoria de "marca de agua" en mi sistema? Respuesta:en un sistema "pequeño", las marcas de agua de zona predeterminadas pueden llegar al 3 % de la memoria. Esto se debe al cálculo de la marca de agua "mín". En sistemas más grandes, las marcas de agua serán una proporción más pequeña, acercándose al 0,3 % de la memoria.

Entonces, si la pregunta es sobre un sistema con más del 10 % de memoria libre, los detalles exactos de esta lógica de marca de agua no son significativos.

Las marcas de agua para cada "zona" individual se muestran en /proc/zoneinfo , como se documenta en proc(5). Un extracto de mi zoneinfo:

Node 0, zone    DMA32
  pages free     304988
        min      7250
        low      9062
        high     10874
        spanned  1044480
        present  888973
        managed  872457
        protection: (0, 0, 4424, 4424, 4424)
...
Node 0, zone   Normal
  pages free     11977
        min      9611
        low      12013
        high     14415
        spanned  1173504
        present  1173504
        managed  1134236
        protection: (0, 0, 0, 0, 0)

Las "marcas de agua" actuales son min , low y high . Si un programa alguna vez solicita suficiente memoria para reducir free por debajo de min , el programa entra en "reclamación directa". El programa está hecho para esperar mientras el kernel libera memoria.

Queremos evitar la reclamación directa si es posible. Así que si free caería por debajo del low marca de agua, el núcleo activa kswapd . kswapd libera memoria intercambiando y/o eliminando cachés, hasta que free está por encima de high de nuevo.

Cualificación adicional:kswapd también se ejecutará para proteger la cantidad completa de lowmem_reserve, para el uso de kernel lowmem y DMA. El lowmem_reserve predeterminado es aproximadamente 1/256 de los primeros 4 GiB de RAM (zona DMA32), por lo que suele rondar los 16 MiB.

Confirmaciones de código Linux

mm:escala kswapd marcas de agua en proporción a la memoria

[…]

marca_de_agua_factor_de_escala:

Este factor controla la agresividad de kswapd. Define la
cantidad de memoria que queda en un nodo/sistema antes de que kswapd se despierte y
cuánta memoria debe estar libre antes de que kswapd vuelva a dormir.

La unidad está en fracciones de 10.000. El valor predeterminado de 10 significa que las
distancias entre las marcas de agua son el 0,1% de la memoria disponible en el
nodo/sistema. El valor máximo es 1000, o el 10 % de la memoria.

Una alta tasa de subprocesos que acceden a la reclamación directa (allocstall) o que kswapd
se va a dormir prematuramente (kswapd_low_wmark_hit_quickly) puede indicar
que la cantidad de páginas libres que kswapd mantiene por razones de latencia es
demasiado pequeña para el ráfagas de asignación que ocurren en el sistema. Esta perilla
se puede usar para ajustar la agresividad de kswapd en consecuencia.

proc:meminfo:calcule la memoria disponible de forma más conservadora

El MemAvailable elemento en /proc/meminfo es dar a los usuarios una pista de cuánta memoria se puede asignar sin causar intercambio, por lo que excluye las marcas de agua bajas de las zonas como no disponibles para el espacio de usuario.

Sin embargo, para una asignación de espacio de usuario, kswapd en realidad reclamará
hasta que las páginas gratuitas alcancen una combinación de la marca de agua alta y la protección de memoria baja del asignador de página
que mantiene una cierta cantidad de memoria DMA
y DMA32 del espacio de usuario también.

Resta la cantidad total que sabemos que no está disponible para el espacio de usuario de
la cantidad de páginas libres al calcular MemAvailable.

Código Linux

A veces se afirma que cambiar swappiness a deshabilitará efectivamente el "intercambio oportunista". Esto proporciona una interesante vía de investigación. Si hay algo llamado "intercambio oportunista", y se puede ajustar mediante swappiness, entonces podríamos perseguirlo encontrando todas las cadenas de llamadas que dicen vm_swappiness . Tenga en cuenta que podemos reducir nuestro espacio de búsqueda asumiendo CONFIG_MEMCG no está configurado (es decir, los “grupos de memoria” están deshabilitados). La cadena de llamadas va:

  • vm_swappiness
  • mem_cgroup_swappiness
  • get_scan_count
  • shrink_node_memcg
  • shrink_nodo
Relacionado:¿Qué RUTA usa `sudo ` para buscar ``?

shrink_node_memcg se comenta “Esta es una página básica por nodo más libre. Utilizado tanto por kswapd como por reclamo directo”. Es decir. esta función aumenta el número de gratis paginas No está tratando de duplicar páginas para intercambiar para que puedan liberarse mucho más tarde. Pero incluso si descontamos eso:

La cadena anterior se llama desde tres funciones diferentes, que se muestran a continuación. Como era de esperar, podemos dividir los sitios de llamada en reclamo directo vs. kswapd. No tendría sentido realizar un "intercambio oportunista" en la recuperación directa.

  1. /*
     * This is the direct reclaim path, for page-allocating processes.  We only
     * try to reclaim pages from zones which will satisfy the caller's allocation
     * request.
     *
     * If a zone is deemed to be full of pinned pages then just give it a light
     * scan then give up on it.
     */
    static void shrink_zones
    
  2.  * kswapd shrinks a node of pages that are at or below the highest usable
     * zone that is currently unbalanced.
     *
     * Returns true if kswapd scanned at least the requested number of pages to
     * reclaim or if the lack of progress was due to pages under writeback.
     * This is used to determine if the scanning priority needs to be raised.
     */
    static bool kswapd_shrink_node
    
  3.  * For kswapd, balance_pgdat() will reclaim pages across a node from zones
     * that are eligible for use by the caller until at least one zone is
     * balanced.
     *
     * Returns the order kswapd finished reclaiming at.
     *
     * kswapd scans the zones in the highmem->normal->dma direction.  It skips
     * zones which have free_pages > high_wmark_pages(zone), but once a zone is
     * found to have free_pages <= high_wmark_pages(zone), any page in that zone
     * or lower is eligible for reclaim until at least one usable zone is
     * balanced.
     */
    static int balance_pgdat
    

Entonces, presumiblemente, la afirmación es que kswapd se activa de alguna manera, incluso cuando todas las asignaciones de memoria se satisfacen inmediatamente desde la memoria libre. Revisé los usos de wake_up_interruptible(&pgdat->kswapd_wait) , y no veo ningún despertar como este.


Linux
  1. Cómo eliminar búferes de memoria y caché en Linux

  2. Linux:¿determinar correctamente el uso de memoria en Linux?

  3. Comando libre en Linux explicado con ejemplos

  4. Linux gratis muestra un alto uso de memoria pero la parte superior no

  5. ¿Cómo funciona la asignación de pila en Linux?

Comando libre de Linux (Comprobar el uso de la memoria)

Comando libre en Linux

¿Linux Oom aleatoriamente cuando todavía hay memoria libre?

¿Cómo funciona el intercambio de memoria en Linux?

Ejemplos de comandos gratuitos en Linux

Encuentra el tamaño de RAM en Linux