Sobes.tech
Middle

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:

  1. Importar net/http/pprof.
  2. Iniciar um servidor HTTP.
  3. Aceder às URLs correspondentes (/debug/pprof/) para obter perfis.
  4. Utilizar a ferramenta go tool pprof para 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.