golangのpprof:メモリリークを修正

まれな例外を除いて(12 <<原稿が悪化しフォーマットされ、IMO)golangに「プロファイリング」についての記事がpprofパッケージ(すらへの注釈の転載ですこの古い記事)した後、助けを借りて成功したか(いない)について少し個人的な経験pprofは問題を見つけます。





ニュアンス

, google "" "" . "" "" "golang pprof" - . , .





, "" . - / , , () . " ", .





: "" - "". ( , .) ( ) " ", ( " ") 20+.





" " - " ". ( ) . , "", "". , " " . "". " " .





  • . , , ( ) "" go. - , goroutines …









, - ́ "pprof.WriteHeapProfile()". : " " "" 512. ( "").





"́ ": "WriteTo()" "" "debug=2":





pprof.Lookup("heap").WriteTo(some_file, 2)
      
      



pprof, . , " " .





  • , "net/http/pprof" curl/wget. , : "http.ListenAndServe()" , . .. "ListenAndServe()" . "go …" goroutine.





pprof ( ). .





1. HeapProfile

import (
	"runtime"
	"runtime/pprof"
)
// Debug: pprof.WriteHeapProfile()
				memprofile := "/run/dnsd/memprofile"
				f, _ := os.Create(memprofile)
				runtime.GC() // get up-to-date statistics
				pprof.WriteHeapProfile(f)
				f.Close()
// Debug: pprof http listener
//	go http.ListenAndServe("localhost:8080", nil)
      
      



  • , . — curl.





2.

( 512 4…6 ), 99% .





goroutine "main.apiCall.func1()" 10923 "". (, .. "" 512 . - …)





# go tool pprof -nodefraction=0 -inuse_objects memprofile.3+
File: dnsd
Type: inuse_objects
Time: Dec 24, 2020 at 10:38am (MSK)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 19387, 100% of 19387 total
Showing top 10 nodes out of 32
      flat  flat%   sum%        cum   cum%
     10923 56.34% 56.34%      10923 56.34%  main.apiCall.func1
      8192 42.26% 98.60%       8192 42.26%  regexp.mergeRuneSets.func2
       256  1.32% 99.92%        256  1.32%  bufio.NewWriterSize
        16 0.083%   100%         16 0.083%  compress/flate.(*dictDecoder).init
      
      



3. /

:





	// To complete report processing even after return on timeout
	go func () {
		defer report.DelNotifier(commands.UUID)

		signals := make(chan os.Signal, 1)
		signal.Notify(signals, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
		for {
			select {
			case index := <-callback:
				if (index + 1) >= len(Workers) {
					done <- struct{}{}
					return
				}
			case t:= <- timer: // t++ on each tick, t=-1 at the end
				if t > 0 {
					xl.Warn("apiCall: Timer tick while still not enough reports from workers!")
				}
				if t < 0 { // Time is over
					xl.Err("apiCall: Time over while still not enough reports from workers!")
					err = fmt.Errorf("Time over")
					done <- struct{}{}
					return
				}
			case exitSignal = <-signals:
				xl.Warnf("apiCall: Interrupt is detected: %s", exitSignal)
				xl.Warn("apiCall: Waiting for timeout to complete report processing...")
				err = fmt.Errorf("Interrupt")
				done <- struct{}{}
				return
			}
		}
	} ()
      
      



4.

, "" "commands.UUID" (commands "" ). , .. "" defer. , . - . - :





go func (uuid string) {
} (commands.UUID)
      
      



SIGKILL (""), . , - - .





, "". - ? :





		signal.Notify(signals, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
      
      



, "defer report.DelNotifier()" . "signal.Notify()" , . , "os.Signal" " " . . , , " ".





, , " ". "" , "" — .





5. Happy end

:





defer signal.Stop(signals)
      
      



, :





# go tool pprof -nodefraction=0 -inuse_objects memprofile.1
File: dnsd
Type: inuse_objects
Time: Dec 25, 2020 at 11:56am (MSK)
No samples were found with the default sample value type.
Try "sample_index" command to analyze different sample values.
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 0, 0% of 0 total
      flat  flat%   sum%        cum   cum%
      
      



() . . " " .





.





, "" ( ""). () , .. "" ( "" ).





golang, , " ". ( ) :





  • . ( " ") "", . — …





  • "" goroutine ( "" ).





  • "defer …" ( - goroutine, ).





  • "" ( "signal.Notify()") .





go1.14. 1.8. 1.8 30 . .





私はgo1.15を試すのを控えなければなりませんでした。潜入しヒップスターが証明書をチェックするときにX.509「CommonName」のサポートを破ったためです。(伝統的に)パブリックインターネットとは別に、あらゆる種類の「クローズド」セグメントがあり、変更を加えるのに大きな遅れがあることを知りません。





以上です。





建設的な批判と「私はどこにいるのか」という指さしは歓迎されます。





この機会を利用して、2021年の皆さん!








All Articles