- 런타임/pprof: 코덱 작업 등과 같은 종료 가능한 코드 블록에 사용되는 분석을 위해 프로그램(비서버)의 실행 데이터를 수집합니다.
- net/http/pprof: 분석을 위해 HTTP Server의 런타임 데이터를 수집합니다. 웹 애플리케이션 등과 같이 종료할 수 없는 코드 블록에 사용됩니다.
사용되는 장면
메모리 누수 분석'
요약하다
이동 중 메모리 누수는 일반적으로 고루틴 누수로 인해 발생합니다. 고루틴이 닫히지 않거나 시간 초과 제어가 추가되지 않아 고루틴이 차단된 상태로 남아 GC를 수행할 수 없습니다.
일시적인 메모리 누수
- 긴 문자열의 세그먼트를 얻으면 긴 문자열이 해제되지 않습니다.
- 긴 슬라이스의 섹션을 얻으면 긴 슬라이스가 해제되지 않습니다.
- 긴 슬라이스에 새 슬라이스를 만들면 누출이 발생합니다.
영구 메모리 누수
- 고루틴 누출
- time.Ticker가 닫히지 않아 누출이 발생함
- 종료자로 인해 누출이 발생함
- 함수 호출을 연기하면 누출이 발생합니다.
Pprof를 사용하는 일반적인 방법( net/http/pprof 포함 ):
1. 네트워크 액세스 방법, 도구로 이동하여 Flame 그래프 보기
프로그램에서 별도의 코루틴을 시작하고, "net/http/pprof" 패키지를 도입하고, 아래와 같이 액세스를 위해 pprof로 다른 포트를 수신합니다.
func setDebug() error {
if config.C.General.Debug != "" {
port := strings.Split(config.C.General.Debug, ":")[1]
log.WithFields(log.Fields{
"profile": "http://127.0.0.1:" + port + "/debug/pprof/profile",
"goroutines": "http://127.0.0.1:" + port + "/goroutines",
}).Info("open prof debug")
go func() {
http.HandleFunc("/goroutines", func(w http.ResponseWriter, r *http.Request) {
num := strconv.FormatInt(int64(runtime.NumGoroutine()), 10)
w.Write([]byte(num))
})
http.ListenAndServe(config.C.General.Debug, nil)
}()
}
return nil
}
또는 프로그램 청취 포트를 직접 공유하십시오. 다음과 같이 package_ "net/http/pprof" 패키지를 소개하세요.
import (
"fmt"
"net/http"
_ "net/http/pprof"
)
func HelloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello world")
}
func main() {
http.HandleFunc("/", HelloWorld)
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println(err)
}
}
먼저 프로그램을 실행한 다음 터미널 창을 열고 go 도구 명령을 실행합니다. 플레임 그래프 툴을 먼저 설치해야 쉽게 볼 수 있으며, 설치 방법은 아래와 같습니다.
go tool pprof -http=:9000 http://localhost:88/debug/pprof/goroutine?debug=1 (모니터링할 서비스 주소)
9000: 최종적으로 플레임 그래프를 볼 수 있는 포트를 나타내며, 실행 후 기본 브라우저가 사용되며 웹페이지가 자동으로 열립니다.
#현재 모든 고루틴의 스택 추적 보기
이동 도구 pprof http://127.0.0.1:8080/debug/pprof/goroutine
# 120초 기다림
이동 도구 pprof http://127.0.0.1:8080/debug/pprof/profile?seconds=120
Flame 그래프 설치 주소 :
시각적 그래픽 소프트웨어 도구 graphviz(https://graphviz.org/download/)를 다운로드하고 설치합니다. Linux, Windows, Mac 등의 해당 버전을 선택할 수 있으며 시스템 환경 변수에 도구를 추가하는 것을 기억하세요. 그렇지 않으면 오류가 보고됩니다: dot 실행에 실패했습니다. Is Graphviz가 설치되어 있습니까? 오류: exec: "dot ": %PATH%에서 실행 파일을 찾을 수 없습니다.
또한 수집 전에 압력 테스트를 수행한 다음 압력 테스트 프로세스 중에 수집할 수 있으므로 분석에 도움이 됩니다 .
go-wrk -c=400 -t=8 -n=100000 http://127.0.0.1:8000/api/getReq
- 400개의 연결, 8개의 스레드, 100,000개의 요청 시뮬레이션
2. 진 프레임워크, 캡슐화 사용
"github.com/gin-contrib/pprof"
프레임워크의 항목은 캡슐화됩니다. 프로그램 시작 후 브라우저를 통해 직접 접근이 가능하며, 실행을 위해 go 도구를 사용할 필요가 없습니다. (프로그램 시작 후 먼저 스트레스 테스트 명령을 실행하면 됩니다.)
http://localhost:88/debug/pprof/ 프로그램에 직접 액세스합니다.
특정 매개변수의 의미
- allocs: 메모리 할당 추상화
- block: 블로킹 스택의 샘플링 정보
- cmdline: 프로그램 시작 명령 및 해당 매개변수
- goroutine: 현재 코루틴의 스택 정보
- heap: 힙 메모리의 샘플링 정보
- mutex: 잠금 경쟁의 샘플링 정보
- 프로필: CPU 사용량 샘플링 정보
- threadcreate: 시스템 프로그램 생성에 대한 샘플링 정보
- Trace : 프로그램 실행에 대한 추적 정보
브라우저에서 그래픽 함수 호출 스택 정보를 볼 수 있습니다. 오른쪽 상단 모서리에 있는 막대 VIEW
에는 클릭하여 볼 수 있는 몇 가지 옵션이 있는데, Flame Graph
이는 전설적인 불꽃 그래프입니다.
Pprof를 사용하는 일반적인 방법( runtime/pprof 포함 ):
도구 유형 애플리케이션 호출은 상대적으로 간단합니다. 주로 런타임/pprof 라이브러리를 사용하여 파일에 데이터를 쓴 다음 보기를 수행합니다.
package main
import (
"flag"
"log"
"os"
"runtime/pprof"
"sync"
)
var (
cpu string
mem string
)
func init() {
flag.StringVar(&cpu, "cpu", "", "write cpu profile to file")
flag.StringVar(&mem, "mem", "", "write mem profile to file")
}
func main() {
flag.Parse()
//采样 CPU 运行状态
if cpu != "" {
f, err := os.Create(cpu)
if err != nil {
log.Fatal(err)
}
_ = pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
var wg sync.WaitGroup
wg.Add(100)
for i := 0; i < 100; i++ {
go workOnce(&wg)
}
wg.Wait()
//采样内存状态
if mem != "" {
f, err := os.Create(mem)
if err != nil {
log.Fatal(err)
}
_ = pprof.WriteHeapProfile(f)
f.Close()
}
}
func counter() {
slice := make([]int, 0)
var c int
for i := 0; i < 10000; i++ {
c = i + 1 + 2 + 3 + 4 + 5
slice = append(slice, c)
}
_ = slice
}
func workOnce(wg *sync.WaitGroup) {
counter()
wg.Done()
}
main.go --cpu=cpu.pprof --mem=mem.pprof를 실행해 보세요.
go 도구 pprof cpu.pprof
파일을 클릭하여 엽니다. (전제조건은 graphviz 도구가 설치되어 있어야 한다는 것입니다)
설치되지 않은 경우 graphviz
나타납니다 Could not execute dot;may need to install graphviz
. graphviz를 설치하는 방법은 다음과 같습니다.
brew install graphviz # for macos
apt-get install graphviz # for ubuntu
yum install graphviz # for centos
성능 도구 사용 추적
1. "런타임/추적" 패키지를 사용하세요.
package main
import (
"fmt"
"log"
"os"
"runtime/trace"
"sync"
)
func main() {
//runtime.GOMAXPROCS(1)
// 1. 创建trace持久化的文件句柄
f, err := os.Create("trace.out")
if err != nil {
log.Fatalf("failed to create trace output file: %v", err)
}
defer func() {
if err := f.Close(); err != nil {
log.Fatalf("failed to close trace file: %v", err)
}
}()
// 2. trace绑定文件句柄
if err := trace.Start(f); err != nil {
log.Fatalf("failed to start trace: %v", err)
}
defer trace.Stop()
var wg sync.WaitGroup
wg.Add(2)
go func() {
fmt.Println(`Hello`)
wg.Done()
}()
go func() {
fmt.Println(`World`)
wg.Done()
}()
wg.Wait()
}
먼저 창을 열고 실행하세요.
main.go를 실행해 보세요
다른 창을 열고 실행
도구 추적 이동 -http=localhost:8080 Trace.out
2023/01/03 11:01:57 추적 파싱 중...
2023/01/03 11:01:57 추적 분할 중...
2023/01/03 11:01:57 브라우저를 여는 중입니다. 추적 뷰어는 http://127.0.0.1:8888에서 수신 중입니다.
추적 보기: 추적 보기
고루틴 분석: 고루틴 분석, 특정 Ctrip 번호 보기
네트워크 차단 프로필: 네트워크 차단 프로필
동기화 차단 프로필: 동기화 차단 프로필
Syscall 차단 프로필: 시스템 호출 차단 프로필
스케줄러 대기 시간 프로필: 스케줄링 지연 프로필, 일반적으로 사용됩니다. , 시간이 소요되는 위치를 분석하는 데 사용됩니다.
사용자 정의 작업: 사용자 정의 작업
사용자 정의 영역: 사용자 정의 영역
최소 mutator 사용률: 최소 Mutator 사용률
참고:
Go 언어 메모리 누수_cqu_jiangzhou의 블로그-CSDN blog_go 메모리 누수
http://liumurong.org/2019/12/gin_pprof/
Go pprof 성능 분석 도구 - 자세한 사용 다이어그램: _dreamer'~ 블로그 - CSDN 블로그_pprof 다이어그램 보는 방법