Introduction to go memory analysis tool -- pprof

I, Xiao Bai, encountered a memory problem when I first came into contact with go. I found a better tool during memory analysis and left a record here.

Don't talk too much nonsense. Just open it.

What is pprof: pprof is Go's performance analysis tool. It can record the running information of the program, including CPU usage, memory usage, goroutine operation, etc. when performance tuning or Bug positioning is required, these recorded information is very important.

Basic usage

There are many ways to use pprof. Go has encapsulated one ready-made: net/http/pprof. With a few simple lines of commands, pprof can be opened to record operation information, and Web services are provided to obtain operation data through browser and command line.

No more nonsense. Let's start with an example:

package main

import (
    "fmt"
    "net/http"
    _ "net/http/pprof"
)

func main() {
    // Listen on request
    ip := "0.0.0.0:6060"
    if err := http.ListenAndServe(ip, nil); err != nil {
        fmt.Printf("start pprof failed on %s\n", ip)
        os.Exit(1)
    }
    // end pprof

    // do something the following is your engineering code
    ........
}

Add the code to the main method as shown in the figure. Then it is to play image - drink tea - wait for image production - wait for image production - wait for image production... Release

Now let's talk about the main operation commands:

(1) Get stack information

$ go tool pprof -inuse_space http://ip:amdin_port/debug/pprof/heap

-inuse_ The space parameter is the memory used by the current service. There is also an -alloc_ The space parameter refers to the total memory allocated since the service was started. The former is more intuitive.

root@sns-ads-service06:~/pprof# go tool pprof -inuse_space http://localhost:6060/debug/pprof/heap
Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in /root/pprof/pprof.123.alloc_objects.alloc_space.inuse_objects.inuse_space.003.pb.gz
File: thriftcapture
Build ID: 1da7c49a46e05f63089a7eecbe14129ad3948566
Type: inuse_space
Time: Apr 14, 2022 at 1:51am (UTC)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)

1. After this command is executed, the legend of memory information will be generated, as shown in the third line in the above figure. You can open the memory diagram for viewing

Saved profile in /root/pprof/pprof.123.alloc_objects.alloc_space.inuse_objects.inuse_space.003.pb.gz

This includes the program name 123, the profile type alloc allocated memory, and inuse represents the memory in use.

I only use two commands, top and list. You can explore other commands by yourself. I won't repeat them. (you can view all commands through the help command)

2. Top command: list the top 10 functions according to the index size. For example, the memory is based on the memory occupation and the CPU is based on the execution time.

root@sns-ads-service06:~/pprof# go tool pprof -inuse_space http://localhost:6060/debug/pprof/heap
Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in /root/pprof/pprof.thriftcapture.alloc_objects.alloc_space.inuse_objects.inuse_space.003.pb.gz
File: thriftcapture
Build ID: 1da7c49a46e05f63089a7eecbe14129ad3948566
Type: inuse_space
Time: Apr 14, 2022 at 1:51am (UTC)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 9034.64kB, 100% of 9034.64kB total
Showing top 10 nodes out of 23
      flat  flat%   sum%        cum   cum%
 5120.23kB 56.67% 56.67%  5120.23kB 56.67%  main.CopyMulty
 2368.33kB 26.21% 82.89%  2368.33kB 26.21%  github.com/buger/goreplay/raw_socket_listener.NewListener
 1034.03kB 11.45% 94.33%  1034.03kB 11.45%  runtime.procresize
  512.05kB  5.67%   100%   512.05kB  5.67%  os.newFile
         0     0%   100%   512.05kB  5.67%  github.com/buger/goreplay/raw_socket_listener.(*Listener).readPcap.func1
         0     0%   100%   512.05kB  5.67%  github.com/buger/goreplay/rlog.(*RLogger).GetMemoryUsageRate
         0     0%   100%   512.05kB  5.67%  github.com/buger/goreplay/rlog.(*logWriter).ReadFile
         0     0%   100%  2368.33kB 26.21%  main.(*RAWInput).listen
         0     0%   100%  2368.33kB 26.21%  main.InitPlugins
         0     0%   100%  2368.33kB 26.21%  main.NewRAWInput
(pprof) root@sns-ads-service06:~/pprof# 

top will list five statistics:

  • flat: the amount of memory occupied by this function.
  • flat%: the percentage of this function's memory in the total memory in use.
  • Sum%: the sum of the flat percentages of each previous line. For example, 100% of the second line is 100% + 0%.
  • cum: it's a cumulative measurement. Adding the main function calls function f, and the memory occupied by function f will also be recorded.
  • cum%: the percentage of cumulative quantity in total quantity.

3. list command: view the code of a function and the indicator information of each line of code of the function. If the function name is unclear, fuzzy matching will be carried out,

Chart to be supplemented

You can see in main The 25th line in main occupies 814.62MB of memory. The left and right data are flat and cum respectively. The meaning is the same as that explained in top.

(2) Compare the memory usage according to the icons generated before and after

By comparison, you can view the memory changes in the previous and subsequent periods.

$ go tool pprof -base pprof.thriftcapture.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz pprof.thriftcapture.alloc_objects.alloc_space.inuse_objects.inuse_space.002.pb.gz

(3) View memory allocation

wget http://localhost:6060/debug/pprof/heap?debug=1

In fact, this command grabs the detailed file of the current memory allocation and generates a local file called heap? For the file with debug = 1, take a look at the specific situation of service memory allocation, or through runtime Memstats get

See the specific file memory produced by yourself

The meaning of indicators is roughly as follows

The following indicators can be used for reference runtime.MemStats Description of response parameters in
    Alloc      uint64 // Number of bytes requested and still in use
    TotalAlloc uint64 // Total number of bytes requested (the released part is also included)
    Sys        uint64 // The number of bytes obtained from the system (the sum of xxsys below) virtual memory
    Lookups    uint64 // Number of pointer lookups
    Mallocs    uint64 // Number of memory requests
    Frees      uint64 // Number of times to free memory
    // Primary allocation heap statistics
    HeapAlloc    uint64 // Number of bytes requested and still in use
    HeapSys      uint64 // The number of bytes obtained from the system
    HeapIdle     uint64 // Number of bytes in idle span
    HeapInuse    uint64 // Number of bytes in non idle span
    HeapReleased uint64 // Number of bytes released to the system
    HeapObjects  uint64 // Total number of allocated objects
    // L statistics of low-level and fixed size structure allocator, Inuse is the number of bytes in use, and Sys is the number of bytes obtained from the system
    StackInuse  uint64 // Bootstrap stack
    StackSys    uint64
    MSpanInuse  uint64 // mspan structure
    MSpanSys    uint64
    MCacheInuse uint64 // mcache structure
    MCacheSys   uint64
    BuckHashSys uint64 // profile bucket hash table
    GCSys       uint64 // GC metadata
    OtherSys    uint64 // Other system applications
    // Garbage collector statistics
    NextGC       uint64 // The next GC is run when the HeapAlloc field reaches this value (number of bytes)
    LastGC       uint64 // Absolute time of last run (nanoseconds)
    PauseTotalNs uint64
    PauseNs      [256]uint64 // The cycle buffer of the recent GC pause time, the last time in [(NumGC+255)%256]
    NumGC        uint32
    EnableGC     bool
    DebugGC      bool

(4) Query goroutine related information

$ wget http://ip:admin_port/debug/pprof/goroutine?debug=1
$ wget http://ip:admin_port/debug/pprof/goroutine?debug=2

debug=1 is to obtain the number and general information of the current goroutines of the service. debug=2 is to obtain the details of the current goroutines of the service and generate goroutines locally? debug=1 and goroutine? debug=2 file,

Picture information will be added later

Continuously updating...

References: Actual Go memory leak - SegmentFault no 

Tags: Go

Posted by ady01 on Sat, 16 Apr 2022 11:09:19 +0930