Quickly Setup Golang pprof and debugging for Memory Leak

Golang pprof gorilla mux memory leak


This post gives you quick steps for debugging memory leak using pprof in Go lang microservices built with Gorilla Mux:
  1. Setting up pprof in Go lang
  2. Running and viewing the memory profile
  3. Pinpointing the code culprit line

Setting up pprof in Go lang

First, you have to include pprof package in your Go file. Go file is the place where you declare your routes:
 import (  
      "encoding/json"  
      "errors"  
      "fmt"  
      "net/http"  
      _ "net/http/pprof"  
      "github.com/gorilla/mux"
 ) 

Then you need to add a path prefix 'debug'. PathPrefix registers a new route with a matcher for the URL path prefix. We do this to see the memory profiler on the browser.
 router := mux.NewRouter()  
 router.PathPrefix("/debug/").Handler(http.DefaultServeMux)  
 router.Path("/healthCheck").Methods("GET").HandlerFunc(s.HealthCheck)  
Do not be confused since pprof package not being used anywhere and simply being imported. Importing only is enough, it takes care of the rest. If you peek into the source code of pprof in %GOROOT%/src/net/http/pprof, you will notice it registers and handles debugging routes automatically in `init` function.
 func init() {  
      http.HandleFunc("/debug/pprof/", Index)  
      http.HandleFunc("/debug/pprof/cmdline", Cmdline)  
      http.HandleFunc("/debug/pprof/profile", Profile)  
      http.HandleFunc("/debug/pprof/symbol", Symbol)  
      http.HandleFunc("/debug/pprof/trace", Trace)  
 }  

Running and viewing memory profile

Anyways moving ahead, run/debug your micro-service and hit "http://localhost:8080/debug/pprof/" on your browser. Notice the port number, it might be different for you. The debugging profile of your code must look like this:


golang pprof debug profile


Your browser must show something like in the above screenshot. Notice the marking in the screenshot `heap`. This is something you need to look into to find your memory leak.


Pinpointing the code culprit line

You are debugging for a memory leak that means, you are up to a point where you could say which API is causing the memory leak. If not then you must try to hit every API and monitor the value against 'heap' in the debugging profile.
golang pprof heap memory profile

If the `heap` value increases by constantly hitting an API, then you can filter out the culprit API. Then to see which code line is creating the issue you must click the `heap` link in the page. You must see something like this:
golang pprof memory profile stack trace allocated mallocs heapreleased
You would see the code stack trace, which is being executed and is not freed. Most of the time the code lines you will see will be from standard packages you imported. But it would give you an idea from the package, that from where you have used the packages in your code and would be able to pin-point the culprit line.


Hope it helps. Happy coding.

Thank you.




Comments

Popular posts from this blog

Effectively Use "cbt" command to get Google Cloud BigTable Data

In Short: SLI, SLO and SLA (and Error Budget)