Che tipo di Garbage Collection usa Go?


111

Go è un linguaggio raccolto dalla spazzatura:

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

Qui dice che è un garbage collector mark-and-sweep, ma non approfondisce i dettagli e una sostituzione è in lavorazione ... tuttavia, questo paragrafo sembra non essere stato aggiornato molto da quando è stato rilasciato Go.

È ancora mark-and-sweep? È conservatore o preciso? È generazionale?


2
Per una lunga discussione sulla storia del netturbino
Wildcard

Risposte:


117

Piani per Go 1.4+ garbage collector:

  • collezionista ibrido stop-the-world / concorrente
  • parte stop-the-world limitata da una scadenza di 10 ms
  • Core della CPU dedicati all'esecuzione del collector simultaneo
  • algoritmo mark-and-sweep tricolore
  • non-generazionale
  • non-compattazione
  • completamente preciso
  • incorre in un piccolo costo se il programma sposta i puntatori
  • latenza inferiore, ma molto probabilmente anche throughput inferiore, rispetto a Go 1.3 GC

Vai agli aggiornamenti del garbage collector 1.3 su Go 1.1:

  • sweep simultaneo (si traduce in tempi di pausa più brevi)
  • completamente preciso

Vai 1.1 garbage collector:

  • mark-and-sweep (implementazione parallela)
  • non-generazionale
  • non-compattazione
  • per lo più preciso (eccetto stack frame)
  • stop-the-world
  • rappresentazione basata su bitmap
  • costo zero quando il programma non alloca memoria (ovvero: mescolare i puntatori è veloce come in C, anche se in pratica funziona un po 'più lentamente di C perché il compilatore Go non è avanzato come i compilatori C come GCC)
  • supporta i finalizzatori sugli oggetti
  • non c'è supporto per riferimenti deboli

Vai 1.0 garbage collector:

  • uguale a Go 1.1, ma invece di essere per lo più preciso, il garbage collector è conservatore. Il GC conservatore è in grado di ignorare oggetti come [] byte.

La sostituzione del GC con uno diverso è controversa, ad esempio:

  • ad eccezione di cumuli molto grandi, non è chiaro se un GC generazionale sarebbe nel complesso più veloce
  • pacchetto "unsafe" rende difficile implementare GC e compattazione GC completamente precisi

Anche l'attuale garbage collector ha un certo grado di parallelismo, quindi può essere eseguito più velocemente su sistemi multi-core.
uriel

3
@uriel: Sì, l'ho menzionato nel primo elemento della mia risposta - il testo "(implementazione parallela)".

Questa risposta è ancora attuale?
Kim Stebel

c # garbage collector è preciso e in c # come in go puoi fare riferimento al membro di un colpito ec # avere una modalità non sicura ma non sono sicuro di come si paragoni per un'implementazione non sicura
skyde

3
Che ne dici di aggiornare questa risposta con 1.5.x solo per creare un buon registro della cronologia.
Ismael

32

(Per Go 1.8 - Q1 2017, vedi sotto )

Il prossimo Garbage Collector Go 1.5 simultaneo implica la possibilità di "ritmo", ha detto gc.
Ecco una proposta presentata in questo documento che potrebbe farcela per Go 1.5, ma aiuta anche a capire il gc in Go.

Puoi vedere lo stato prima della 1.5 (Stop The World: STW)

Prima di Go 1.5, Go utilizzava un raccoglitore parallelo stop-the-world (STW).
Sebbene la raccolta STW abbia molti aspetti negativi, ha almeno un comportamento di crescita dell'heap prevedibile e controllabile.

https://40.media.tumblr.com/49e6556b94d75de1050c62539680fcf9/tumblr_inline_nr6qq8D9FE1sdck2n_540.jpg

(Foto dalla presentazione del GopherCon 2015 " Go GC: Solving the Latency Problem in Go 1.5 ")

L'unica manopola di sintonia per il raccoglitore STW era "GOGC", la relativa crescita del mucchio tra le collezioni. L'impostazione predefinita, 100%, attivava la garbage collection ogni volta che la dimensione dell'heap era raddoppiata rispetto alla dimensione dell'heap live della raccolta precedente:

https://docs.google.com/drawings/image?id=sLJ_JvGfPfPnojLlEGLCWkw&rev=1&h=113&w=424&ac=1

Temporizzazione GC nel raccoglitore STW.

Go 1.5 introduce un collector simultaneo .
Questo ha molti vantaggi rispetto alla raccolta STW, ma rende la crescita dell'heap più difficile da controllare perché l'applicazione può allocare memoria mentre il garbage collector è in esecuzione .

https://40.media.tumblr.com/783c6e557b427a5c023520578740eb94/tumblr_inline_nr6qqpmaJx1sdck2n_540.jpg

(Foto dalla presentazione del GopherCon 2015 " Go GC: Solving the Latency Problem in Go 1.5 ")

Per ottenere lo stesso limite di crescita dell'heap, il runtime deve avviare la raccolta dei dati obsoleti prima, ma quanto prima dipende da molte variabili, molte delle quali non possono essere previste.

  • Avvia il collector troppo presto e l'applicazione eseguirà troppe operazioni di Garbage Collection, sprecando le risorse della CPU.
  • Avvia il collector troppo tardi e l'applicazione supererà la crescita massima dell'heap desiderata.

Raggiungere il giusto equilibrio senza sacrificare la concorrenza richiede un attento ritmo del garbage collector.

Il pacing GC mira a ottimizzare lungo due dimensioni: crescita dell'heap e CPU utilizzata dal Garbage Collector.

https://docs.google.com/drawings/image?id=sEZYCf7Mc0E0EGmy4gho3_w&rev=1&h=235&w=457&ac=1

Il design della stimolazione GC è costituito da quattro componenti:

  1. uno stimatore per la quantità di lavoro di scansione richiesto da un ciclo GC,
  2. un meccanismo che consente ai mutatori di eseguire la quantità stimata di lavoro di scansione nel momento in cui l'allocazione dell'heap raggiunge l'obiettivo dell'heap,
  3. uno scheduler per la scansione in background quando mutator aiuta a sottoutilizzare il budget della CPU, e
  4. un controller proporzionale per il trigger GC.

Il design bilancia due diverse visualizzazioni del tempo: tempo CPU e tempo heap .

  • Il tempo della CPU è come il tempo dell'orologio da parete standard, ma passa GOMAXPROCSpiù velocemente.
    Cioè, se GOMAXPROCSè 8, allora passano otto secondi CPU ogni secondo wall e GC ottiene due secondi di tempo CPU ogni secondo wall.
    Lo scheduler della CPU gestisce il tempo della CPU.
  • Il passaggio del tempo di accumulo viene misurato in byte e avanza quando i mutatori vengono allocati.

La relazione tra il tempo di heap e il tempo di wall dipende dal tasso di allocazione e può cambiare costantemente.
Mutator aiuta a gestire il passaggio del tempo di heap, assicurando che il lavoro di scansione stimato sia stato completato nel momento in cui l'heap raggiunge la dimensione dell'obiettivo.
Infine, il controller di trigger crea un ciclo di feedback che lega insieme queste due visualizzazioni del tempo, ottimizzando sia il tempo di heap che gli obiettivi di tempo della CPU.


20

Questa è l'implementazione del GC:

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

Dai documenti nella fonte:

Il GC viene eseguito contemporaneamente ai thread mutator, è accurato al tipo (ovvero preciso), consente l'esecuzione in parallelo di più thread GC. È un mark and sweep simultaneo che utilizza una barriera di scrittura. È non generazionale e non compattante. L'allocazione viene eseguita utilizzando dimensioni separate per aree di allocazione P per ridurre al minimo la frammentazione eliminando i blocchi nel caso comune.


8

Go 1.8 GC potrebbe evolversi di nuovo, con la proposta "Elimina la nuova scansione dello stack STW"

A partire da Go 1.7, l'unica fonte rimanente di tempo stop-the-world (STW) illimitato e potenzialmente non banale è la nuova scansione dello stack.

Proponiamo di eliminare la necessità di una nuova scansione dello stack passando a una barriera di scrittura ibrida che combina una barriera di scrittura per la cancellazione in stile Yuasa [Yuasa '90] e una barriera di scrittura per l'inserimento in stile Dijkstra [Dijkstra '78] .

Esperimenti preliminari mostrano che questo può ridurre il tempo STW nel caso peggiore a meno di 50 µs e questo approccio può rendere pratico eliminare del tutto la terminazione del marchio STW.

L' annuncio è qui e puoi vedere che il commit della fonte pertinente è d70b0fe e precedenti.


3

Non ne sono sicuro, ma penso che l'attuale (suggerimento) GC sia già parallelo o almeno sia un WIP. Quindi la proprietà stop-the-world non si applica più o non lo sarà nel prossimo futuro. Forse qualcun altro può chiarirlo in modo più dettagliato.


7
È fermare il mondo. GC potenzialmente funziona in parallelo dopo che il mondo è stato fermato. Probabilmente intendevi GC simultaneo.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.