pprof: CPU, heap, goroutine, mutex и block profiles

pprof собирает агрегированные профили runtime. Начинать нужно с симптома и воспроизводимой нагрузки: CPU profile отвечает «где исполнялся CPU-код», heap — «что удержано», alloc — «где выделяли», mutex/block — «где наблюдалось ожидание».

Зачем это на интервью

Сильный ответ различает типы профиля, flat и cum, не называет верхнюю строку автоматически причиной p99 и повторяет измерение после исправления.

Минимум для E4

  • Снимать CPU и memory profiles тестом или net/http/pprof.
  • Открывать go tool pprof -http=:0 profile и читать top, list, flame graph.
  • Отличать inuse_space от alloc_space.
  • Ограничивать pprof endpoint сетью и аутентификацией.
go test ./... -run '^$' -bench '^BenchmarkParse$' -cpuprofile=cpu.out -memprofile=mem.out
go tool pprof -http=:0 cpu.out
go tool pprof -sample_index=alloc_space mem.out
curl -o cpu.pb.gz 'http://127.0.0.1:6060/debug/pprof/profile?seconds=20'
go tool pprof cpu.pb.gz

Углубление для E5/Senior

Импорт blank net/http/pprof регистрирует handlers на DefaultServeMux; не подключайте его к публичному mux случайно. CPU profile sampling-овый и не показывает время ожидания I/O. Heap profile по умолчанию фокусируется на in-use; -sample_index=alloc_space помогает искать allocation rate и GC pressure. Goroutine profile — снимок стеков текущих goroutine; рост сам по себе требует сравнения и классификации состояний.

Mutex и block profiles имеют sampling/overhead-настройки (runtime.SetMutexProfileFraction, runtime.SetBlockProfileRate) и включаются осознанно на короткий период. При lock contention изучают владельца lock, длительность critical section и архитектуру данных, а не просто меняют Mutex на RWMutex. Всегда сравнивают одинаковый workload и сопровождают оптимизацию correctness tests и сервисными SLI.

Ключевые понятия

ПрофильВопрос
CPUгде процесс исполнял инструкции
heap/inuseчто удерживалось в момент снимка
allocгде выделено больше всего за период
goroutineкакие стеки и goroutine существуют
mutex/blockгде наблюдалось ожидание locks/синхронизации

Типовые вопросы

  1. Что такое flat и cum? — Flat относится к самой функции, cumulative включает вызовы ниже в стеке.
  2. alloc_space — это leak? — Нет: это поток аллокаций; leak ищут по удержанию (inuse) и тренду после нагрузки.
  3. Почему CPU profile не объясняет p99? — Хвост может быть I/O, очередью, GC или lock waiting, где CPU не занят.
  4. Когда нужен goroutine profile? — При подозрении на leak, зависшие workers или неожиданный рост concurrency; стеки сравнивают во времени.
  5. Безопасен ли /debug/pprof/? — Нет по умолчанию: доступ ограничивают, профиль берут кратко и удаляют артефакт по политике.

Практика

  • Создайте CPU-hotspot и allocation-hotspot. Готово: собраны profile files, выбран верный sample index и различены результаты.
  • Добавьте lock contention. Готово: mutex/block profile сопоставлен с workload, исправление подтверждено повтором и тестом.

Частые ошибки и ловушки

  • Сравнивать profiles с разным traffic или duration.
  • Объявлять любую аллокацию утечкой.
  • Оставлять pprof публичным или тяжёлое профилирование включённым постоянно.

Связанные темы

Инструменты Go · Бенчмарки · Trace и escape analysis

Источники