Como medir o uso de memória em Go e o que é pprof?
sobes.tech IA
Resposta da IA
A utilização de memória em Go pode ser medida de várias formas:
-
runtime.MemStats: Fornece uma instantânea das estatísticas de utilização de memória, incluindo o tamanho do heap, o número de objetos, a recolha de lixo, etc. É útil para obter uma visão geral da distribuição de memória.
-
Perfilador pprof: Uma ferramenta poderosa para analisar o desempenho e o uso de recursos, incluindo memória. Permite recolher perfis do uso do heap em diferentes momentos e analisá-los para identificar gargalos e fugas de memória.
-
debug.FreeOSMemory(): Liberta memória de forma forçada ao sistema operativo. Pode ajudar indiretamente a entender quanto de memória é retida pelo runtime de Go.
pprof (net/http/pprof) é um pacote na biblioteca padrão de Go que se integra com o perfilador pprof do pacote runtime/pprof. Fornece interfaces HTTP para recolher perfis de diversos recursos, incluindo CPU, heap (memória), bloqueios, goroutines e mutexes.
Para usá-lo:
- Importar
net/http/pprof. - Iniciar um servidor HTTP.
- Aceder às URLs correspondentes (
/debug/pprof/) para obter perfis. - Utilizar a ferramenta
go tool pprofpara analisar os dados recolhidos.
Exemplo de uso de runtime.MemStats:
import (
"fmt"
"runtime"
"time"
)
func main() {
var m runtime.MemStats
runtime.ReadMemStats(&m) // Ler estatísticas de memória
fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
fmt.Printf("\tNumGC = %v\n", m.NumGC)
// Exemplo de trabalho com memória
_ = make([]byte, 1024*1024*10) // Alocar 10MB
time.Sleep(100 * time.Millisecond) // Esperar que o GC possa executar
runtime.ReadMemStats(&m)
fmt.Printf("Após alocação: Alloc = %v MiB", bToMb(m.Alloc))
fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
fmt.Printf("\tNumGC = %v\n", m.NumGC)
}
func bToMb(b uint64) uint64 {
return b / 1024 / 1024
}
Exemplo de uso do pprof num servidor HTTP:
import (
_ "net/http/pprof" // Importar para registar os manipuladores pprof
"net/http"
"log"
)
func main() {
log.Println(http.ListenAndServe(":6060", nil)) // Ouvir na porta 6060
}
Após iniciar este código, pode aceder a http://localhost:6060/debug/pprof/ para obter diferentes perfis. Para analisar o heap, pode usar go tool pprof http://localhost:6060/debug/pprof/heap.