(Para Go 1.8 - Q1 2017, ver más abajo )
El próximo recolector de basura concurrente de Go 1.5 implica poder "marcar el ritmo", dijo gc.
Aquí hay una propuesta presentada en este documento que podría ser compatible con Go 1.5, pero también ayuda a comprender el gc en Go.
Puede ver el estado antes de 1.5 (Stop The World: STW)
Antes de Go 1.5, Go utilizaba un colector paralelo de stop-the-world (STW).
Si bien la recopilación de STW tiene muchas desventajas, al menos tiene un comportamiento de crecimiento de montón predecible y controlable.
(Foto de la presentación de GopherCon 2015 " Go GC: Resolviendo el problema de latencia en Go 1.5 ")
La única perilla de ajuste para el colector STW era "GOGC", el crecimiento relativo del montón entre colecciones. La configuración predeterminada, 100%, activaba la recolección de basura cada vez que el tamaño del montón se duplicaba sobre el tamaño del montón en vivo de la colección anterior:
Sincronización de GC en el colector STW.
Go 1.5 presenta un colector concurrente .
Esto tiene muchas ventajas sobre la recolección de STW, pero dificulta el control del crecimiento del montón porque la aplicación puede asignar memoria mientras se ejecuta el recolector de basura .
(Foto de la presentación de GopherCon 2015 " Go GC: Resolviendo el problema de latencia en Go 1.5 ")
Para lograr el mismo límite de crecimiento del montón, el tiempo de ejecución debe comenzar la recolección de basura antes, pero cuánto antes depende de muchas variables, muchas de las cuales no se pueden predecir.
- Inicie el recolector demasiado pronto y la aplicación realizará demasiadas recolecciones de basura, desperdiciando recursos de la CPU.
- Inicie el recopilador demasiado tarde y la aplicación superará el crecimiento de pila máximo deseado.
Lograr el equilibrio adecuado sin sacrificar la simultaneidad requiere que el recolector de basura pasee con cuidado.
El ritmo de GC tiene como objetivo optimizar en dos dimensiones: el crecimiento del montón y la CPU utilizada por el recolector de basura.
El diseño de la estimulación GC consta de cuatro componentes:
- un estimador de la cantidad de trabajo de escaneo que requerirá un ciclo de GC,
- un mecanismo para que los mutadores realicen la cantidad estimada de trabajo de escaneo para cuando la asignación del montón alcance el objetivo del montón,
- un programador para escaneo en segundo plano cuando el mutador ayuda a subutilizar el presupuesto de la CPU, y
- un controlador proporcional para el gatillo del GC.
El diseño equilibra dos vistas diferentes del tiempo: tiempo de CPU y tiempo de pila .
- El tiempo de CPU es como el tiempo estándar de un reloj de pared, pero pasa
GOMAXPROCS
más rápido.
Es decir, si GOMAXPROCS
es 8, pasan ocho segundos de CPU por segundo de pared y GC obtiene dos segundos de tiempo de CPU por segundo de pared.
El programador de la CPU administra el tiempo de la CPU.
- El paso del tiempo de pila se mide en bytes y avanza a medida que los mutadores asignan.
La relación entre el tiempo de pila y el tiempo de pared depende de la tasa de asignación y puede cambiar constantemente.
Mutator ayuda a gestionar el paso del tiempo de pila, asegurando que el trabajo de escaneo estimado se haya completado para cuando la pila alcance el tamaño objetivo.
Por último, el controlador de disparo crea un bucle de retroalimentación que une estas dos vistas del tiempo, optimizando tanto el tiempo de pila como los objetivos de tiempo de CPU.