Un fallo de página en swap provoca una pausa de 40 ms en el recolector de basura de Go

A 40ms Go garbage collector pause caused by swap

Un fallo de página en swap provoca una pausa de 40 ms en el recolector de basura de Go

El recolector de basura de Go lee metadatos fuera del heap durante pausas stop-the-world. Si el kernel ha enviado esas páginas a swap, cada lectura genera un fallo de página importante. En pruebas con kernel 6.8 y MGLRU, la pausa mediana fue de 51 µs, pero la peor alcanzó 40 ms, con 228 fallos de página que consumieron 39 ms. Además, construir un mensaje de 511 KiB pasó de 3-5 ms a 105 ms en NVMe y 903 ms en un volumen de red.

39 de esos 40 ms se gastaron en 228 fallos de página.
  1. nasretdinov

    Lamentablemente, eso es algo esperado: independientemente de la implementación, el simple hecho de que el GC necesite de alguna manera recorrer todo el árbol para rastrear las secciones aún referenciadas hace que el swap sea altamente impráctico; incluso si no hubieras tenido pausas stop-the-world de 40 ms, la caché LRU utilizada por el swap se descartaría en cada GC.

    Creo que esa es en realidad la misma razón por la que Apple dejó de usar GC en sus frameworks en favor del conteo automático de referencias.

  2. jacobgold

    "Me duele cuando hago esto"

    "Deja de hacer eso"

    Si te importa la latencia, desactiva el swap. A nivel de sistema o para el cgroup específico.

  3. pizlonator

    ¿Hay alguna razón por la que Go no esté usando GC on the fly, donde no hay STW en absoluto?

  4. xavdid

    Discord aprendió esto en 2020 y publicó una gran entrada de blog al respecto: https://discord.com/blog/why-discord-is-switching-from-go-to...

  5. soltanov

    Un SLO de latencia de GC debería incluir la presión de memoria del sistema operativo. De lo contrario, un problema de fallo de página parecerá un problema del recolector y llevará a la solución equivocada.

  6. Gabrys1

    Empecé a preguntarme si podría haber un GC consciente del swap, como primero hacer que la página requerida se traiga del swap (aunque no hay una API obvia para eso...) y solo entonces pausar el mundo.

  7. imclaren

    Esto. Los bugs de inflación de memoria son relativamente fáciles de corregir en Go, pero a veces es una aventura eliminar la inflación de swap. ¡Y creo que vale la pena eliminar toda la inflación de swap!

  8. faangguyindia

    Uso Go donde usaría Node, Ruby o Python.

    Uso Rust donde necesito baja latencia.

Más de este día

2026-10-05