简体   繁体   中英

Does ticker.C leak memory, if run forever?

I've searched stack overflow for something similar to this, and couldn't find exactly what I was looking for. I apologize if this is an obvious mistake as I just recently started writing in Go, but I appreciate any explanation in advance. I currently have a go routine that ranges over the values of *Ticker . Now this go routine runs the entire time my program is alive, as it checks for necessary updates. I started recognizing that my program leaks memory slowly overtime. It starts to become very noticeable after 20 to 30 hours of running.

func (s *Server) checkForUpdates() { // go routine
    ticker := time.NewTicker(time.Minute * time.Duration(s.checkTime)) //x.checkTime = 2 minutes
    defer ticker.Stop()
    for t := range ticker.C { // will loop every 2 minutes
         fmt.Println("the update check happened at %d\n", t)
         // do the updates
    }
}

I narrowed the leak down to the go routine, and read up on all the way's Time can leak memory. Making sure that you close the *Ticker you created once your done with the go routine. However my program runs forever until I kill it. So this go routine will forever run, until I decide to stop the program. I know this might be silly to think, but I thought it might be the t := range ticker.C part that could be the problem. Because that loop never stops until I kill. So t never get's released. So I thought the := re-declares the variable every time I loop? I then made the loop to :

for _ = range ticker.C { // completely got rid of declaration of time.Time
   // do updates ...
}

And so far it seems to be working... but I really don't understand why, or maybe it should have not helped, and there's something else I'm doing wrong.

I appreciate any help/explanation for this. Thank you.

As @Cerise Limon pointed out it is most likely your application leaking memory in the logic its doing. In order to pinpoint exactly what is leaking memory you can use pprof to show the total memory in use by statement. This is a method for answering any question like:

  • "Which part of the application is using the most memory at a point in time?"
  • "Which part of the application is responsible for the most memory allocations? (in byte size)"
  • "which part of the application (if any) is growing in size over time"
  • "how much memory is a given statement/line using at a point in time?"

Once pprof is enabled you can take memory profiles by using:

$ curl http://localhost:8080/debug/pprof/heap > heap.0.pprof

You can then interact with the profile using the cli:

$ go tool pprof pprof/heap.3.pprof
Local symbolization failed for main: open /tmp/go-build598947513/b001/exe/main: no such file or directory
Some binary filenames not available. Symbolization may be incomplete.
Try setting PPROF_BINARY_PATH to the search path for local binaries.
File: main
Type: inuse_space
Time: Jul 30, 2018 at 6:11pm (UTC)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) svg
Generating report in profile002.svg
(pprof) top20
Showing nodes accounting for 410.75MB, 99.03% of 414.77MB total
Dropped 10 nodes (cum <= 2.07MB)
      flat  flat%   sum%        cum   cum%
  408.97MB 98.60% 98.60%   408.97MB 98.60%  bytes.Repeat
    1.28MB  0.31% 98.91%   410.25MB 98.91%  main.(*RequestTracker).Track
    0.50MB  0.12% 99.03%   414.26MB 99.88%  net/http.(*conn).serve
         0     0% 99.03%   410.25MB 98.91%  main.main.func1
         0     0% 99.03%   410.25MB 98.91%  net/http.(*ServeMux).ServeHTTP
         0     0% 99.03%   410.25MB 98.91%  net/http.HandlerFunc.ServeHTTP

Which will show you how much memory is inuse in your application and which statements/lines are responsible.

What's also cool is that you can generate graphviz charts of your program in order to visualize and trace current memory usage (or memory allocations):

在此处输入图片说明


There are quite a few blog posts about pprof online (including standard documentation).

I wrote a bit about it:

And then there are many amazing resources, two of which are:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM