2013-09-29 12 views
5

Sto scrivendo il mio primo programma webserver/webservices in Go e mi sono reso conto che il RSIZE (come mostrato dal programma a riga di comando "top") cresce dopo aver ripetuto la stessa richiesta ai miei webservices. Significa che c'è una perdita di memoria?Utilizzo della memoria Go (lang): crescente in RSIZE e VSIZE di 139 GB?

Ho anche notato che sia il mio app che il processo go su "top" hanno un VSIZE di 139 GB (entrambi di esattamente le stesse dimensioni). È normale?

Sto usando Go 1.1.2 su OS X 10.8

Molte grazie

+0

Il grande VSIZE è normale su darwin. RSIZE si livella mai o continua a crescere? – JimB

+0

Ho notato esattamente la stessa cosa su OSX 10.7, quindi presumo che la cosa VSIZE sia normale. Non sembra influenzare negativamente le prestazioni. – Aktau

risposta

2

Big VSIZE non significa che sei veramente utilizzando la memoria fisica; non mi preoccuperei di quello

RSIZE in crescita anche dopo una singola richiesta non è preoccupante. La RAM viene recuperata dalla garbage collection, che costa i cicli della CPU, quindi Go e altri linguaggi di GC aspettano molte richieste finché non hanno bisogno della RAM liberata (o almeno fino a che molta RAM è stata allocata) per eseguire una raccolta. Meno raccolte => meno tempo di CPU speso.

Le perdite nel senso comune sono rare perché il GC dovrebbe alla fine liberare memoria a cui non si sta facendo riferimento. Se si hanno buffer che crescono secondo necessità ma non si restringono mai, questi possono avere un effetto di perdita e se si tiene accidentalmente un riferimento alla memoria che è davvero morto si possono avere problemi. Ma a meno che il processo non cresca per sempre, non presumo che tu stia avendo questo problema qui.

Ecco alcuni suggerimenti per la gestione della memoria per Go; alcuni si applicano indirettamente anche ad altre lingue:

  • Spesso non è necessario preoccuparsi. La raccolta è spesso piuttosto veloce e spesso hai un sacco di RAM per giocare con le dimensioni dei tuoi dati. Prima di tuffarti, assicurati che ci sia un problema da risolvere. :)
  • runtime.ReadMemStats(ms) può dire per quanto tempo il vostro programma è trascorso in GC, insieme a molte altre informazioni utili come quanto si sta allocazione (vedi runtime docs modulo a http://golang.org/pkg/runtime/)
  • Se stai spendendo troppo tempo in GC e non so perché, memprofile è il prossimo passo; un esempio completo che implica la concessione di un programma una bandiera facoltativa -memprofile è sul blog Go: http://blog.golang.org/profiling-go-programs
  • In generale, si riducono i GC riducendo le allocazioni non necessarie, in particolare le allocazioni di oggetti di grandi dimensioni (buffer che contengono risposte HTTP intere, ad esempio). A volte ci sono modi naturali per farlo senza sporcare il tuo programma - puoi riutilizzare un oggetto attraverso diverse iterazioni di un ciclo invece di allocarlo ogni volta, per esempio. Altre volte, puoi riciclare vecchi oggetti invece di crearne di nuovi; il pacchetto standard sync.Pool aiuta con questo, e c'è una bella descrizione generale del riciclaggio (da prima che lo standard sync.Pool fosse standard) on the CloudFlare blog.

Buon divertimento!