Sobes.tech
Middle

¿Cómo se puede medir el uso de memoria en Go y qué es pprof?

sobes.tech AI

Respuesta de la IA

El uso de memoria en Go se puede medir de varias maneras:

  • runtime.MemStats: Proporciona una instantánea de las estadísticas de uso de memoria, incluyendo el tamaño del montón, el número de objetos, la recolección de basura, etc. Es útil para obtener una visión general de la distribución de memoria.

  • Perfilador pprof: Una herramienta potente para analizar el rendimiento y el uso de recursos, incluyendo memoria. Permite recopilar perfiles del uso del montón en diferentes momentos y analizarlos para identificar cuellos de botella y fugas de memoria.

  • debug.FreeOSMemory(): Libera memoria de forma forzada al sistema operativo. Puede ayudar indirectamente a entender cuánta memoria retiene el runtime de Go.

pprof (net/http/pprof) es un paquete en la biblioteca estándar de Go que se integra con el perfilador pprof del paquete runtime/pprof. Proporciona interfaces HTTP para recopilar perfiles de diversos recursos, incluyendo CPU, memoria (el montón), bloqueos, goroutines y mutexes.

Para usarlo:

  1. Importar net/http/pprof.
  2. Iniciar un servidor HTTP.
  3. Acceder a las URLs correspondientes (/debug/pprof/) para obtener perfiles.
  4. Utilizar la utilidad go tool pprof para analizar los datos recopilados.

Ejemplo de uso de runtime.MemStats:

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
	var m runtime.MemStats
	runtime.ReadMemStats(&m) // Leer estadísticas de memoria
	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)

	// Ejemplo de uso de memoria
	_ = make([]byte, 1024*1024*10) // Asignar 10MB

	time.Sleep(100 * time.Millisecond) // Esperar a que el GC pueda ejecutarse

	runtime.ReadMemStats(&m)
	fmt.Printf("Después de asignar memoria: 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
}

Ejemplo de uso de pprof en un servidor HTTP:

import (
	_ "net/http/pprof" // Importar para registrar los manejadores pprof
	"net/http"
	"log"
)

func main() {
	log.Println(http.ListenAndServe(":6060", nil)) // Escuchar en el puerto 6060
}

Después de ejecutar este código, se puede acceder a http://localhost:6060/debug/pprof/ para obtener diferentes perfiles. Para analizar el heap, se puede usar go tool pprof http://localhost:6060/debug/pprof/heap.