Sobes.tech
Middle

Как да измерим използването на памет в Go и какво е pprof?

sobes.tech AI

Отговор от AI

Използването на памет в Go може да се измери по няколко начина:

  • runtime.MemStats: Предоставя snapshot на статистиката за използването на паметта, включително размера на купчината, броя на обектите, събиране на боклука и др. Полезен е за получаване на обща представа за разпределението на паметта.

  • Профайлер pprof: Мощен инструмент за анализ на производителността и използването на ресурси, включително памет. Позволява събиране на профили на използването на купчината в различни моменти и анализиране за откриване на тесни места и течове на памет.

  • debug.FreeOSMemory(): Принудително освобождава паметта към операционната система. Може косвено да помогне да се разбере колко памет държи Go рантаймът.

pprof (net/http/pprof) — това е пакет в стандартната библиотека на Go, който се интегрира с профайлъра pprof от пакета runtime/pprof. Той предоставя HTTP интерфейси за събиране на профили на различни ресурси, включително CPU, купчина (памет), блокировки, goroutine и мьютекси.

За да го използвате:

  1. Импортирайте net/http/pprof.
  2. Стартирайте HTTP сървър.
  3. Посетете съответните URL адреси (/debug/pprof/) за достъп до профилите.
  4. Използвайте утилитата go tool pprof за анализ на събраните данни.

Пример за използване на runtime.MemStats:

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

func main() {
	var m runtime.MemStats
	runtime.ReadMemStats(&m) // Четем статистиката за паметта
	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)

	// Пример за работа с паметта
	_ = make([]byte, 1024*1024*10) // Задаваме 10MB

	time.Sleep(100 * time.Millisecond) // Изчакваме GC да се изпълни

	runtime.ReadMemStats(&m)
	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)
}

func bToMb(b uint64) uint64 {
	return b / 1024 / 1024
}

Пример за използване на pprof в HTTP сървър:

import (
	_ "net/http/pprof" // Импортираме за регистрация на обработчиците на pprof
	"net/http"
	"log"
)

func main() {
	log.Println(http.ListenAndServe(":6060", nil)) // Слушаме на порт 6060
}

След стартиране на този код, можете да посетите адрес http://localhost:6060/debug/pprof/ и да получите достъп до различни профили. За анализ на купчината, използвайте go tool pprof http://localhost:6060/debug/pprof/heap.