tl; dr:
- Non è possibile utilizzare TB di RAM con un unico processo Go al momento. Max è 512 GB su Linux e la maggior parte di quelli che ho visto è di 240 GB.
- Con lo sfondo attuale GC, il carico di lavoro GC tende ad essere più importante di GC pause.
- Si può capire il carico di lavoro GC come puntatori * tasso di assegnazione/RAM ricambio. Di app che utilizzano tonnellate di RAM, solo quelle con pochi puntatori o poca allocazione avranno un carico di lavoro GC basso.
Sono d'accordo con il commento di inf che enormi cumuli sono la pena di chiedere altre persone circa (o test). JimB rileva che gli heap di Go hanno un limite rigido di 512 GB al momento, e 240 GB è il più che ho visto testato.
Alcune cose che sappiamo su enormi cumuli, da the design document e the GopherCon 2015 slides:
Folks esecuzione coppia le app di produzione che inizialmente presentavano pause di circa 300 ms sono state ridotte a ~4ms e ~20ms. Un'altra app ha riferito che il tempo del GC al 95 ° percentile è passato da 279ms to ~10ms.
Go 1.6 added polish and pushed some of the remaining work to the background. Come risultato, i test con cumuli fino a un po 'più di 200GB ha visto ancora un tempo di pausa massimo di 20 ms, come mostrato in a slide nei primi del 2016 State of Go talk:
La stessa applicazione che ha avuto 20ms tempi di pausa sotto 1.5 aveva 3-4ms pauses under 1.6, with about an 8GB heap and 150M allocations/minute.
Twitch, che utilizza Go per il proprio servizio di chat, ha segnalato che by Go 1.7 pause times had been reduced to 1ms with lots of running goroutines.
1.8 took stack scanning out of the stop-the-world phase, portando la maggior parte delle pause ben al di sotto di 1 ms, anche su grandi cumuli. Early numbers look good. Occasionalmente le applicazioni hanno ancora schemi di codice che rendono difficile la pausa di una goroutine, allungando in modo efficace la pausa per tutti gli altri thread, ma in generale è giusto dire che il lavoro di background del GC di solito è molto più importante di GC pause.
Alcune osservazioni di carattere generale in materia di raccolta dei rifiuti, non specifiche per Go:
riformulato, un'applicazione l'accesso a grandi quantità di memoria potrebbe ancora non avere un problema GC se ha solo alcune indicazioni (ad esempio, gestisce relativamente pochi grandi []byte
buffer), e le collezioni accadere meno spesso se il tasso di allocazione è basso (ad es. perché hai applicato sync.Pool
per riutilizzare la memoria ovunque eri a masticare nella RAM più velocemente).
Quindi, se siete alla ricerca di qualcosa che coinvolge un sacco di centinaia di GB che non è naturalmente GC-friendly, io suggerirei di prendere in considerazione qualsiasi
- scritta in C o come
- spostando il ingombranti dati fuori dal grafico dell'oggetto. Ad esempio, è possibile gestire i dati in un DB incorporato come
bolt
, inserirli in un servizio DB esterno o utilizzare qualcosa come groupcache
o memcache se si desidera più di una cache di un DB
- in esecuzione un set di heap più piccolo ' d processi invece di uno grande
- solo con attenzione la prototipazione, il test e l'ottimizzazione per evitare problemi di memoria.
Interessante domanda, potrebbe essere una scelta migliore per i golang-nuts, però. La dimensione del ram – inf
non ha importanza. ram USAGE conta. se usi solo qualche concerto di quella ram, un ciclo GC deve solo occuparsi di quei pochi concerti. se si assegna la TB completa come blocco singolo, di nuovo è banale da gestire. "questo puntatore è ancora in uso?" –
sì, ovviamente intendevo l'uso della ram :) –