La fragmentación de la memoria en el funcionamiento del servidor significa que los bloques grandes y contiguos ya no están disponibles a pesar de la RAM libre y las asignaciones críticas fallan. Muestro las causas, los síntomas típicos y las contramedidas específicas para que Servidor reaccionan de forma calculable y las asignaciones se pueden función.
Puntos centrales
- Interno y externo Diferenciar y abordar específicamente la fragmentación.
- Asignador de amigos Comprender: Pedidos, divisiones, fusiones que faltan.
- Esquiador de fondo-Configurar correctamente las cargas de trabajo, la sobrecarga del hipervisor y el THP.
- Diagnóstico con buddyinfo, vmstat y métricas de compactación.
- Patrón de asignación mejorar: Pools, preasignación, vidas separadas.
¿Qué significa la fragmentación de la memoria en el uso cotidiano de los servidores?
Me refiero como Memoria La fragmentación es el estado en el que la memoria de trabajo libre se divide en muchos huecos pequeños y las peticiones grandes ya no reciben un área contigua. La fragmentación interna se produce cuando un bloque asignado es mayor que la necesidad real y quedan bytes sin utilizar en el bloque, lo que puede provocar la Eficacia se reduce. La fragmentación externa se produce cuando las secciones libres se distribuyen y ya no se juntan para formar un área grande, aunque haya suficiente RAM libre en total. Aquí es precisamente donde fallan los búferes grandes, las reservas JIT o los controladores que favorecen la memoria contigua debido a la aparentemente paradójica escasez de bloques grandes. En entornos de alojamiento, las altas cargas paralelas, los largos tiempos de actividad y las pilas de software heterogéneas agravan este problema. Dinámica notable.
Cómo el Linux-Buddy-Allocator crea fragmentación
El núcleo Linux gestiona la memoria física a través de un Buddy-allocator, que organiza las páginas en clases de tamaño (órdenes), a partir de 4 KB. Si los procesos solicitan áreas mayores, el núcleo divide los bloques grandes en "buddies" hasta que se dispone de un tamaño adecuado; cuando se liberan, intenta reunir los "buddies". Sin embargo, las diferentes longitudes de las peticiones, los cambios en los tiempos de vida y las liberaciones desiguales impiden el reensamblaje y fomentan la utilización de servidores externos. Fragmentación. Con el tiempo, el stock de pedidos grandes se vacía, mientras que los pedidos pequeños se hinchan - /proc/buddyinfo muestra entonces números altos en los pedidos bajos y ceros en los pedidos altos. A partir de este momento, la compactación y posiblemente el comportamiento OOM intervienen con mayor frecuencia, lo que genera latencias y aumenta las interrupciones.
Causas en entornos de alojamiento y virtualización
Las cargas de trabajo web y de bases de datos de larga duración crean un patrón variable de asignaciones que divide los bloques grandes y permite que más tarde Fusión impedido. Los frameworks y librerías que liberan memoria tarde o de forma descoordinada dejan huecos en los que sólo se pueden acomodar pequeñas peticiones. La virtualización añade su propia sobrecarga y desplaza las asignaciones al huésped y al hipervisor, lo que significa que las peticiones externas de memoria no pueden ser satisfechas. Fragmentación se crea más rápidamente. Los valores vm.min_free_kbytes configurados incorrectamente aumentan la presión porque el núcleo tiene muy pocos búferes para las asignaciones atómicas o los reserva en exceso. Más transparencia sobre Memoria virtual me ayuda a organizar ordenadamente la interacción entre el asignador de invitados, THP, Huge Pages y el hipervisor.
Efectos sobre el rendimiento y la experiencia del usuario
Si el tanque de almacenamiento se divide en muchas islas pequeñas, el Latencias, porque el núcleo comprime y se desplaza con más frecuencia antes de poder atender grandes peticiones. Las aplicaciones que requieren áreas continuas -como bases de datos, cachés o conductos multimedia- flaquean más rápidamente. A pesar de la RAM „libre“, las grandes asignaciones fallan y generan mensajes de error, reinicios o cancelaciones forzosas, que pueden provocar sesiones y Transacciones perjudicados. Las actividades en segundo plano, como la compactación, aumentan la carga de la CPU y la presión de E/S, haciendo que incluso las cargas de trabajo más ligeras parezcan más lentas. En los escenarios de alojamiento, esto se manifiesta en tiempos de respuesta largos, tiempos de espera esporádicos y peor escalado durante los picos de carga.
Diagnóstico: de buddyinfo a las métricas de compactación
Primero compruebo /proc/buddyinfo para ver qué Pedidos vmstat y sar muestran la frecuencia con la que el núcleo compacta o si la ruta OOM se ha activado, lo que indica la presión de las grandes asignaciones. Utilizo perf y strace para reconocer si los hilos están esperando la compactación directa y, por tanto, los tiempos de respuesta fluctúan, lo que se nota en los registros y las métricas. En entornos con servidores Windows, visualizo los heaps fragmentados con herramientas de depuración para comprobar si hay grandes huecos y ajustar los parámetros del heap. ajustar. También mido el bloque libre más grande, porque la suma de RAM libre no es suficiente como diagnóstico.
Kernel y VM tuning en la práctica
Yo pongo vm.min_free_kbytes moderadamente más alto, a menudo en el corredor de 5-10 % de RAM, de modo que el núcleo puede utilizar grandes, atómica Consultas puede funcionar de forma fiable. Activo las páginas gigantes transparentes con precaución: a la carta o a través de madvise, en función del perfil de carga y del riesgo de fragmentación. Las páginas gigantes estáticas ofrecen previsibilidad, pero requieren una planificación adecuada para no causar problemas en otros lugares. Cuellos de botella para crear orden. La compactación activa el orden a corto plazo, pero no sustituye a una solución estructural para patrones permanentes e inestables. Incluyo topologías NUMA en el ajuste para que las grandes asignaciones sigan siendo locales y no se dispersen por los nodos.
| Configuración | Objetivo | Beneficio | Nota |
|---|---|---|---|
| vm.min_free_kbytes | Reserva para grandes asignaciones | Menos picos de OOM/compactación | Aumentar gradualmente y medir el valor |
| THP (sobre/consejo) | Favorecer las páginas más grandes | Menos fragmentación, mejor ratio TLB | Atención a las latencias de la carga de trabajo |
| Páginas enormes (estático) | Reservar zonas continuas | Grandes bloques predecibles | Planificar la capacidad con antelación |
| Compactación | Reunir las zonas libres | Bloques temporalmente más grandes | Aumenta la CPU/I&O a corto plazo |
| NUMA-Política | Asignación local segura | Menor latencia, menos tráfico cruzado | Configurar el equilibrio |
Zonas de almacenamiento, tipos de migración y por qué „inamovible“ lo bloquea todo
El asignador de páginas no sólo funciona con órdenes, sino también con zonas (DMA, DMA32, Normal, Movible) y Migrar tipos (MOVIBLE, INAMOVIBLE, RECUPERABLE). Los gránulos para esto son los „bloqueos de página“. En cuanto las páginas INMUEBLES (por ejemplo, estructuras del núcleo, páginas fijadas por los controladores) entran en un bloque de página, el núcleo marca este bloque como difícil de mover. Son precisamente estos bloques „contaminados“ los que impiden que la compactación combine las áreas libres en grandes bloques contiguos. Zonas formas. Por ello, planifico conscientemente la capacidad en ZONE_MOVABLE (siempre que es posible) y me aseguro de que los datos de las aplicaciones se asignen predominantemente como MOVABLE. Esto significa que es más probable que las reservas grandes y contiguas permanezcan disponibles. Para cargas de trabajo con elevados requisitos de DMA, utilizo reservas dirigidas para que las páginas UNMOVABLE no destruyan la zona normal amplia.
Diseño limpio del patrón de asignación
Agrupo las necesidades de almacenamiento según Vida útilLos objetos de corta vida en pools, los de larga vida en regiones separadas para que las liberaciones no lo destrocen todo en general. Agrupo los tamaños frecuentes en pools fijos para reducir la fluctuación de pedidos y aliviar al buddy allocator. Planifico previamente los buffers grandes al principio en lugar de solicitarlos en medio del tráfico, lo que evita picos de carga al agrupar. Adapto las solicitudes de alineación a las necesidades reales, ya que las alineaciones excesivas malgastan espacio y fomentan la carga interna. Fragmentación. En los procesos de creación y despliegue, pruebo las rutas de almacenamiento con escenarios de carga antes de que el tráfico llegue al sistema.
Selección de asignadores en el espacio de usuario: glibc, jemalloc, tcmalloc
No todas las fragmentaciones son un problema del núcleo. El sitio Espacio usuario-allocator tiene una gran influencia en el patrón que el buddy allocator ve al final. glibc malloc usa arenas por hilo; en muchos núcleos esto puede llevar a una alta fragmentación interna. Limito el número de arenas y recorto más agresivamente para que las áreas no usadas fluyan de vuelta al sistema operativo más rápidamente. Alternativas como jemalloc o tcmalloc ofrecen clases de tamaño más finas y patrones de compartición más consistentes, que pueden reducir notablemente la fragmentación externa. El factor decisivo es: Mido bajo carga de producción, porque cada asignador tiene diferentes compensaciones en latencia, rendimiento y huella de memoria. Para servicios con un alto rendimiento y tamaños de objetos uniformes, las arenas dedicadas o los pools tipo slab suelen ofrecer el rendimiento más estable. Latencias.
Medidas del lado de la aplicación: Java, PHP, cachés y bases de datos
En Java utilizo Arenas o asignador de regiones y elija perfiles de GC que favorezcan las reservas grandes y contiguas en lugar de romper constantemente el montón en trozos finos. Equilibro Xms/Xmx para que el montón no crezca y se reduzca constantemente, ya que este bombeo favorece los agujeros. Para las pilas de PHP y MySQL, utilizo pools de memoria fijos, limito los objetos sobredimensionados y optimizo los tamaños de los búferes con el objetivo de conseguir patrones de asignación coherentes. Optimización PHP/MySQL. Organizo los sistemas de caché (por ejemplo, cachés de objetos o de páginas) para que los trozos tengan un tamaño uniforme, de modo que los lanzamientos no dejen grandes huecos. Si nada más ayuda, planifico reinicios controlados en ventanas de mantenimiento en lugar de arriesgarme a eventos OOM no planificados que pueden destruir todo el sistema. Servicios para anularlo.
Práctica de contenedores y Kubernetes
Los contenedores no cambian la funcionalidad del Buddy-asignadores- sólo segmentan vistas y límites. Por tanto, la fragmentación sigue siendo un problema del host, pero se manifiesta en los pods a través de desalojos, latencias fluctuantes o costes de división THP. Logro la estabilidad mediante:
- Configure las clases de QoS (Garantizada/Ráfaga) para que los pods críticos reciban reservas fijas y no crezcan y decrezcan al mismo tiempo.
- límites de memoria de forma realista, de modo que el recorte y la recuperación no violen permanentemente los límites de memoria dura. Límites chocan.
- THP/Hugepages es consistente en todo el host y proporciona a los pods que necesitan páginas grandes pools reservados estáticamente.
- Utilizar estrategias de calentamiento (pre-fallo, pre-asignación) para que los bloques grandes se ocupen pronto y no se soliciten más tarde bajo carga.
Monitorizo los nodos en contenedores como si fueran bare metal: buddyinfo, eventos de compactación, OOM kills - sólo que también los correlaciono con pod restarts y evictions para separar la causa limpiamente.
Virtualización, NUMA e influencias del hardware
Entre los hipervisores, compruebo cómo interactúan el asignador de invitados, el ballooning y el THP del host porque la estratificación puede aumentar la fragmentación y crear grandes Bloquea la hace escasa. Observo sistemáticamente las topologías NUMA: la asignación local reduce la latencia y evita que las peticiones grandes se distribuyan por los nodos y, por tanto, se reduzcan. Cuando tiene sentido, asigno cargas de trabajo a los nodos NUMA y observo el efecto sobre los fallos de página y los accesos a la TLB. Para un control más preciso, establezco directrices para los nodos de almacenamiento y extraigo Equilibrio NUMA de forma selectiva. También incluyo actualizaciones de firmware y microcódigo para poder descartar efectos secundarios inesperados y garantizar la previsibilidad con grandes Requisitos recibir.
Controlador de dispositivo, DMA y CMA
Conductores que están físicamente coherente áreas (por ejemplo, ciertos motores DMA, multimedia, tarjetas de captura) exacerban la fragmentación externa. Aquí planeo utilizar el asignador de memoria contigua (CMA) o reservar grandes bloques al principio del proceso de arranque. Esto evita que muchas asignaciones pequeñas „roan“ el espacio de direcciones antes de que el controlador obtenga sus búferes. Al mismo tiempo, aíslo las páginas pinned (por ejemplo, usando RDMA/DPDK) de la memoria general de la aplicación para que su carácter UNMOVABLE no inutilice bloques de páginas enteros. También debería comprobar si las configuraciones de IOMMU virtualizan suficientemente las áreas más grandes y no contiguas; de lo contrario, necesitaría reservas específicas y límites de tiempo claros. Windows para estas asignaciones.
Rutina operativa: haga un uso inteligente de las ventanas de supervisión y mantenimiento
Incrusto instantáneas de buddyinfo, contadores de compactación y eventos OOM en mi Monitoreo, para ver tendencias en lugar de eventos individuales. Reduzco los despliegues continuos para que la fluctuación de memoria se concentre en ventanas de tiempo y el resto de la semana transcurra con más fluidez. Durante las ventanas de mantenimiento, activo manualmente la compactación si es necesario, limpio las cachés y reinicio los servicios antes de que la fragmentación cause problemas productivos. Correlaciono los registros y las métricas con los picos de tráfico para reconocer patrones recurrentes y ajustar los búferes en consecuencia. Cuando se trata de cambios importantes, primero los pruebo en la fase de pruebas para no descubrir cambios sorprendentes. Efectos secundarios en funcionamiento.
Runbook: Cuando las grandes asignaciones fallan hoy
Si hay mensajes de error agudos „falló la asignación de la orden X“, trabajo en pasos claros:
- Cuadro de situación: Guardar buddyinfo, comprobar vmstat (allocstall/compact), buscar entradas de Compaction/OOM en dmesg. Estima el bloque libre más grande (orden más alto con >0).
- Alivio a corto plazo: Ponga en pausa los servicios no críticos, estrangule la carga, limpie las cachés de forma selectiva. Active la compactación manualmente y desactive temporalmente THP Defrag si está causando daños.
- Despeje selectivo: Reconstruir buffers grandes y contiguos en servicios definidos (reinicio controlado) antes de que se produzca el siguiente pico.
- Aumentar la reserva: vm.min_free_kbytes y watermark cuidadosamente para asegurar asignaciones atómicas para las próximas horas; efectos tight monitor.
- Remedio permanente: Corrige los patrones de asignación, introduce pools, mueve la preasignación al inicio, comprueba la localización NUMA y ajusta THP/Huge Pages adecuadamente.
Variables medidas, SLO y alarmas
No sólo mido los totales de RAM, sino que también defino SLOs para la asignabilidad: „orden más alto con disponibilidad“, „tiempo hasta la asignación satisfactoria de grandes cantidades“, „porcentaje de bloqueo de la compactación“. De ahí se derivan alarmas que se activan pronto, antes de que los usuarios vean los tiempos de espera. Algunos ratios útiles son
- Número de bloques libres en órdenes altos (por ejemplo, ≥ Orden-9) por minuto.
- Frecuencia y duración de los tiempos de espera de compactación directa o recuperación.
- Proporción de páginas ancladas/no ancladas en relación con la memoria total.
- Porcentaje de éxito de las grandes asignaciones en las pruebas de carga y tras las implantaciones.
Vinculo estas métricas a los tiempos de lanzamiento, los picos de tráfico y los cambios de configuración. De este modo, reconozco patrones según los cuales puedo proactivamente escala o reprogramar la ventana de asignación.
Planificación de la capacidad y conciencia de los costes
Calculo los márgenes de almacenamiento de forma que tanto Funcionamiento normal y se cubren adecuadamente las fases de mantenimiento con mayores asignaciones. En lugar de ampliar de forma generalizada, primero compruebo las correcciones de muestra, porque una buena puesta a punto suele aportar más que la RAM adicional. Cuando amplío la capacidad, planifico en reservas para THP/páginas enormes para que las páginas grandes no choquen con los picos de las aplicaciones. La consolidación en menos hosts pero más potentes puede reducir la fragmentación, siempre que configure NUMA y los perfiles de asignación adecuadamente. La conclusión es que ahorro costes en euros cuando reduzco la fragmentación porque disminuyo los picos de CPU y la congestión de E/S y utilizo las licencias de forma más eficiente. utilice.
Brevemente resumido
La fragmentación de la memoria se produce cuando se enlazan muchas asignaciones de diferentes longitudes y tamaños. Zonas y las grandes consultas luego se quedan en nada. Resuelvo el problema en tres frentes: Kernel/VM tuning (vm.min_free_kbytes, THP/Huge Pages), mejores patrones de asignación (pools, pre-asignación, tiempos de vida separados) y gestión limpia de operaciones (monitorización, poda programada, disciplina NUMA). Me baso en /proc/buddyinfo, los contadores de compactación y la medición del bloque libre más grande para el diagnóstico, porque los totales puros de RAM son engañosos. Presto atención explícita a la virtualización y a los hipervisores para que el huésped y el anfitrión no trabajen el uno contra el otro y para que no se produzcan grandes pérdidas de memoria. Bloquea reservado en una fase temprana. La combinación de estos elementos básicos aumenta la previsibilidad, evita fallos debidos a OOM y ofrece respuestas más rápidas, especialmente cuando el tráfico y los datos crecen.


