0

I have a memory leak in a small program. In order to find the leak, I would like to use pprof.

I set it up like this:

func main() {
    f, _ := os.Create("my_pprof.pprof")
    pprof.StartCPUProfile(f)

    go func() {
        main2()
    }()

    time.Sleep(1*time.Minute)
    pprof.StopCPUProfile()
    f.Close()
    panic("QUIT")
}

When I want to generate the graph, I have the error:

$ go tool pprof --pdf my_prog my_pprof.pprof > callgraph.pdf
No nodes to print

Why isn't possible to get nodes?

UPDATE: This program will reproduce the issue.

package main

import (
    "fmt"
    "os/exec"
    "time"
    "os"
    "log"
    "runtime/pprof"
)

func pollExec() {
    ticker := time.NewTicker(5 * time.Millisecond)
    quit := make(chan struct{})
    for {
        select {
            case <-ticker.C:
                const command = "cat"
                const arg= "my_project/src/probe/test_pprof.go"
                log.Printf("Execute command: " + command + " " + arg)
                cmd := exec.Command(command, arg)
                out, err := cmd.Output()
                if err != nil {
                    panic("Can't execute command: " + command)
                }
                fmt.Printf("Output: %s\n", out)

            case <-quit:
                ticker.Stop()
                return
        }
    }
}


func main() {
    const pprofFileName = "my_project/src/probe/test.pprof"
    f, err := os.Create(pprofFileName)
    if err != nil {
        panic("Can't open file: " + pprofFileName)
    }
    pprof.StartCPUProfile(f)

    go func() {
        pollExec()
    }()

    time.Sleep(1*time.Minute)
    pprof.StopCPUProfile()
    f.Close()
    panic("QUIT")
}

I run it on:

$ uname -a
Linux ubuntu 3.13.0-34-generic #60-Ubuntu SMP Wed Aug 13 15:45:27 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

The global context is that I have a very small program pushing information based on a Unix command result. The program size is around 3MB, I have only 40MB ram to run it 24/7. When I leave the example running, the size is growing and growing. I don't know where the leak is and I am very uncomfortable with go as this is my first program in this language. For the example provided in this post, the memory consumption increased with the time:

 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                            
16723 paralle+  20   0    6408   1700    816 S   2.0  0.2   0:00.52 test_pprof
After few minutes…
16723 paralle+  20   0    6408   1960    832 S   1.7  0.2   0:04.76 test_pprof  
sberry
  • 128,281
  • 18
  • 138
  • 165
Julio
  • 2,493
  • 4
  • 33
  • 53
  • it works for me. Are you sure the prof file is created ok? what's the size of it? you're not checking the error from opening it, any chance you simply can't? – Not_a_Golfer Feb 10 '15 at 08:45
  • 1
    Maybe your code simply does not enough work? CPU profiling is done by sampling. What happens if you run pprof interactively? – Volker Feb 10 '15 at 09:07
  • Are you on Linux? What kernel version? Older kernels (>~9yrs) have problems. https://code.google.com/p/gperftools/issues/detail?id=335 – Intermernet Feb 10 '15 at 09:15
  • @Julio is the memory growing when you are not running the cpu profiling? – Not_a_Golfer Feb 10 '15 at 10:13
  • @Not_a_Golfer: Yes the memory consumption is growing slowly (from 1876 to 1996 in 30 minutes). Maybe the garbage collector is not flushing when the memory consumption is to slow? – Julio Feb 10 '15 at 10:58
  • @Julio you can tune the GC collection threshold. The default is 100% (meaning your process can use up to twice the memory it actually uses), but if you are short on memory, try a value in the range of 10-20%. – Not_a_Golfer Feb 10 '15 at 11:29
  • 1
    @Julio see http://golang.org/pkg/runtime/debug/#SetGCPercent – Not_a_Golfer Feb 10 '15 at 11:31

0 Answers0