example español collector garbage-collection go

español - ¿Qué tipo de Garbage Collection usa Go?



garbage collector python (5)

(Para Go 1.8 - Q1 2017, ver a continuación )

El próximo recolector de basura concurrente de Go 1.5 implica poder "acelerar" dicho GC.
Aquí hay una propuesta presentada en este documento que podría ser para Go 1.5, pero también ayuda a entender el gc en Go.

Puedes ver el estado antes de 1.5 (Stop The World: STW)

Antes de Go 1.5, Go ha utilizado un colector paralelo stop-the-world (STW).
Si bien la recolecció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: Cómo resolver el problema de latencia en Go 1.5 ")

La perilla de sintonización exclusiva para el colector STW era "GOGC", el crecimiento relativo del montón entre las colecciones. La configuración predeterminada, 100%, desencadenó la recolección de elementos no utilizados cada vez que el tamaño del almacenamiento dinámico se duplicó sobre el tamaño del almacenamiento dinámico en vivo como en la colección anterior:

Tiempo de GC en el colector STW.

Go 1.5 presenta un recopilador simultáneo .
Esto tiene muchas ventajas sobre la recolección de STW, pero hace que el crecimiento del montón sea más difícil de controlar porque la aplicación puede asignar memoria mientras el recolector de basura está en ejecución .

(Foto de la presentación de GopherCon 2015 " Go GC: Cómo resolver el problema de latencia en Go 1.5 ")

Para lograr el mismo límite de crecimiento de almacenamiento dinámico, el tiempo de ejecución debe iniciar la recolección de basura más temprano, pero cuánto tiempo antes depende de muchas variables, muchas de las cuales no pueden predecirse.

  • Inicie el recopilador demasiado pronto, y la aplicación realizará demasiadas recolecciones de basura, desperdiciando recursos de CPU.
  • Inicie el recopilador demasiado tarde y la aplicación excederá el crecimiento de montón máximo deseado.

Lograr el equilibrio correcto sin sacrificar la simultaneidad requiere un ritmo cuidadoso del recolector de basura.

La estimulación de GC busca optimizar en dos dimensiones: crecimiento de pila y CPU utilizada por el recolector de basura.

El diseño de estimulación GC consta de cuatro componentes:

  1. un estimador para la cantidad de trabajo de escaneo que requerirá un ciclo GC,
  2. un mecanismo para que los mutadores realicen la cantidad estimada de trabajo de escaneo en el momento en que la asignación del montón alcance el objetivo del montón,
  3. un programador para el escaneo en segundo plano cuando el mutador ayuda a subutilizar el presupuesto de la CPU, y
  4. un controlador proporcional para el gatillo GC.

El diseño equilibra dos vistas diferentes de tiempo: tiempo de CPU y tiempo de montón .

  • El tiempo de CPU es como el tiempo de reloj de pared estándar, pero pasa GOMAXPROCS veces más rápido.
    Es decir, si GOMAXPROCS es 8, entonces ocho segundos de CPU pasan cada segundo de pared y GC obtiene dos segundos de tiempo de CPU cada segundo de pared.
    El programador de CPU administra el tiempo de CPU.
  • El paso del tiempo de almacenamiento dinámico se mide en bytes y avanza a medida que se asignan los mutadores.

La relación entre el tiempo de acumulación y el tiempo de pared depende de la tasa de asignación y puede cambiar constantemente.
Mutator ayuda a administrar el paso del tiempo de montón, asegurando que el trabajo de escaneo estimado se haya completado para cuando el montón llegue al tamaño del objetivo.
Finalmente, el controlador disparador crea un ciclo de retroalimentación que une estas dos vistas del tiempo, optimizando tanto el tiempo de almacenamiento como los objetivos de tiempo de CPU.

Go es un lenguaje recogido de basura:

http://golang.org/doc/go_faq.html#garbage_collection

Aquí dice que es un recolector de basura con marca y barrido, pero no profundiza en los detalles, y un reemplazo está en proceso ... sin embargo, este párrafo parece no haberse actualizado mucho desde que se lanzó Go.

Todavía es marca y barrido? ¿Es conservador o preciso? ¿Es generacional?


Esta es la implementación del GC:

https://github.com/golang/go/blob/master/src/runtime/mgc.go

De los documentos en la fuente:

El GC se ejecuta simultáneamente con los hilos del mutador, es de tipo preciso (también conocido como preciso), permite que múltiples hilos del GC se ejecuten en paralelo. Es una marca concurrente y un barrido que usa una barrera de escritura. No es generacional y no es compactante. La asignación se realiza utilizando el tamaño segregado por áreas de asignación P para minimizar la fragmentación y, al mismo tiempo, eliminar bloqueos en el caso común.


Go 1.8 GC podría evolucionar de nuevo, con la propuesta "Eliminar STW stack re-scanning"

A partir de Go 1.7, la única fuente restante de tiempo ilimitado y potencialmente no trivial stop-the-world (STW) es la re-escaneo de la pila.

Proponemos eliminar la necesidad de reescaneo de pila cambiando a una barrera de escritura híbrida que combina una barrera de escritura de eliminación Yuasa [Yuasa ''90] y una barrera de escritura de inserción de estilo Dijkstra [Dijkstra ''78] .

Los experimentos preliminares muestran que esto puede reducir el tiempo de STW en el peor de los casos a menos de 50 μs , y este enfoque puede hacer que sea práctico eliminar por completo la terminación de la marca STW.

El anuncio está aquí y puede ver que la confirmación de fuente relevante es d70b0fe y anterior.


No estoy seguro, pero creo que el GC (punta) actual ya es paralelo o al menos es un WIP. Por lo tanto, la propiedad stop-the-world ya no se aplicará o no lo hará en el futuro cercano. Quizás alguien más pueda aclarar esto con más detalle.


Planes para el recolector de basura Go 1.4+:

  • híbrido stop-the-world / coleccionista concurrente
  • Parte del mundo limitado por una fecha límite de 10ms
  • Núcleos de CPU dedicados a ejecutar el recopilador concurrente
  • algoritmo tricolor de marcaje y barrido
  • no generacional
  • no compactación
  • totalmente preciso
  • incurre en un pequeño costo si el programa está moviendo punteros alrededor
  • menor latencia, pero probablemente también menor rendimiento, que Go 1.3 GC

Vaya a las actualizaciones del recolector de basura 1.3 en la parte superior de Go 1.1:

  • barrido concurrente (resultados en tiempos de pausa más pequeños)
  • totalmente preciso

Ir 1.1 recolector de basura:

  • mark-and-sweep (implementación paralela)
  • no generacional
  • no compactación
  • mayormente preciso (excepto marcos de pila)
  • parar el mundo
  • representación basada en mapas de bits
  • costo cero cuando el programa no asigna memoria (es decir: mezclar punteros es tan rápido como en C, aunque en la práctica esto se ejecuta un poco más lento que C porque el compilador Go no es tan avanzado como los compiladores C como GCC)
  • admite finalizadores en objetos
  • no hay soporte para referencias débiles

Go 1.0 basurero:

  • Igual que Go 1.1, pero en lugar de ser muy preciso, el recolector de basura es conservador. El GC conservador puede ignorar objetos como [] byte.

Reemplazar el GC con uno diferente es controvertido, por ejemplo:

  • a excepción de montones muy grandes, no está claro si un GC generacional sería más rápido en general
  • El paquete "inseguro" hace que sea difícil implementar GC totalmente compactos y compactos