Тикер.С утечка памяти, если работает вечно? - PullRequest
0 голосов
/ 19 марта 2019

Я искал переполнение стека для чего-то похожего на это и не смог найти именно то, что искал.Я прошу прощения, если это очевидная ошибка, поскольку я только недавно начал писать на Go, но я заранее благодарен за любое объяснение.В настоящее время у меня есть процедура go, которая находится в диапазоне значений *Ticker.Теперь эта процедура запускается все время, пока моя программа жива, так как она проверяет наличие необходимых обновлений.Я начал осознавать, что моя программа со временем теряет память.Это начинает становиться очень заметным после 20-30 часов работы.

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
    }
}

Я сузил утечку до рутины, и прочитал все время Time может утечка памяти.Убедитесь, что вы закрыли *Ticker, который вы создали, как только вы закончили с рутиной go.Однако моя программа работает вечно, пока я не убью ее.Так что эта процедура будет работать вечно, пока я не решу остановить программу.Я знаю, что это может быть глупо думать, но я подумал, что это может быть проблема с t := range ticker.C.Потому что этот цикл никогда не останавливается, пока я не убью.Так что t никогда не выйдет.Поэтому я подумал, что := повторно объявляет переменную каждый раз, когда я зацикливаюсь?Затем я сделал цикл:

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

И до сих пор, кажется, это работает ... но я действительно не понимаю, почему, или, возможно, это не должно было помочь, и есть кое-что еще, что я 'Я делаю неправильно.

Я ценю любую помощь / объяснение этого.Спасибо.

1 Ответ

3 голосов
/ 19 марта 2019

Как отметил @Cerise Limon, наиболее вероятно, что ваше приложение теряет память в логике своей работы.Чтобы точно определить, какая утечка памяти, вы можете использовать pprof, чтобы показать общий объем памяти, используемый оператором.Это метод ответа на любой вопрос, такой как:

  • «Какая часть приложения использует больше памяти в определенный момент времени?»
  • "Какая часть приложения отвечает за наибольшее количество выделяемой памяти? (В байтовом размере)"
  • "какая часть приложения (если есть) увеличивается со временем"
  • «сколько памяти использует данный оператор / строка в определенный момент времени?»

После включения pprof вы можете использовать профили памяти с помощью:

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

Затем вы можете взаимодействовать с профилем, используя 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

, который покажет вам, сколько памяти используется в вашем приложении и какие операторы / строки несут ответственность.

Чтотакже здорово то, что вы можете генерировать графики графиков своей программы для визуализации и отслеживания текущего использования памяти (или выделения памяти):

enter image description here


Есть довольно много сообщений в блоге о pprof онлайн (включая стандартную документацию).

Я немного об этом написал:

И еще есть много удивительных ресурсов, два из которых:

...