SlideShare a Scribd company logo
1 of 18
Download to read offline
golang profilingの基礎
CA.go#1 (2017/06/21)
株式会社AbemaTV 中澤優⼀郎
⾃⼰紹介
中澤 優⼀郎 (はせ)
経歴
•2012/06~ AmebaスマートフォンPF
•2014/01~ 『タップル誕⽣』
•2015/12~ 『AbemaTV』
Golang歴 2年
Profiling of golang
pprof (runtime/pprof)
• GolangのProfilingを⾏うパッケージ
• CPU・Memory・goroutineなどの情報を収集
• protocol buffer形式でプロファイルを保存
• `go tool pprof` によりプロファイルを分析
runtime/pprof
CPU Profiler
• 関数の実⾏時間をプロファイリング
• (UNIX) settimerを利⽤し10msごとに
SIGPROFシグナル送信
• サンプラはシグナルをハンドリングし
スタックトレースを保存
f,	err	:=	os.Create(*cpuprofile)

if	err	!=	nil	{

			log.Fatal("could	not	create	CPU	profile:	",	err)

}

if	err	:=	pprof.StartCPUProfile(f);	err	!=	nil	{

			log.Fatal("could	not	start	CPU	profile:	",	err)

}

defer	pprof.StopCPUProfile()
runtime/pprof
CPU Proflier以外のProfilerはLookupで呼び出し
f,	err	:=	os.Create("./mem.prof")	
if	err	!=	nil	{	
log.Fatal("could	not	create	memory	profile:	",	err)	
}	
defer	func()	{	
pprof.Lookup("heap").WriteTo(f,	0)	
				f.Close()	
}()
runtime/pprof
“heap” (Heap Profiler)
• メモリの情報(GCとアロケーション)をプロファイリング
“goroutine” (Goroutine Profiler)
• 実⾏中のgoroutineのプロファイリング
heap options
(go tool pprof -inuse_space mem.prof )
-inuse_space 利⽤中のメモリ領域
-inuse_objects メモリ利⽤中のオブジェクト数
-alloc_space 前回のGCからアロケートされたメモリ領域
runtime/pprof
“block” (Blocking Profiler)
※ runtime.SetBlockProfileRate を 1 以上に設定することで有効化
• 同期処理でwaitingしているgoroutineをプロファイリング
“mutex” (Mutex Profiler) ※go1.8から追加
※ runtime.SetMutexProfileFraction を 1 以上に設定することで有効化
• 同期処理をブロックする ”mutexのみ” をプロファイリング
• time.Tickerなどパフォーマンスに深刻な影響を与えない項⽬は表⽰されない
runtime/pprof
Custom Profilers
Profilerの実装によりカスタムプロファイラを作成可能
import	“runtime/pprof"	
prof	:=	pprof.New(“custom”)	
prof.Add(obj,	1)	
prof.Remove(1)
Relational Packages
runtime/pprof
net/http/pprof
•HTTP Server⽤のプロファイラ
github.com/pkg/profile
•`runtime/pprof` をより簡単に利⽤できるようなwrapper
•元はdevecheneyの `https://github.com/davecheney/profile`
net/http/pprof
Web Server向けpprofパッケージ
• http経由でプロファイリングを取得
• 2種類のバインド⽅法
• DefaultServeMuxにバインド (blank
import)
• ServeMuxをNewしてバインド
import	(	
		"net/http"	
		"net/http/pprof"	
		"runtime"	
)	
---	
		mux	:=	http.NewServeMux()	
		mux.Handle("/debug/pprof/",	http.HandlerFunc(pprof.Index))	
		mux.Handle("/debug/pprof/cmdline",	http.HandlerFunc(pprof.Cmdline))	
		mux.Handle("/debug/pprof/profile",	http.HandlerFunc(pprof.Profile))	
		mux.Handle("/debug/pprof/symbol",	http.HandlerFunc(pprof.Symbol))	
		mux.Handle("/debug/pprof/trace",	http.HandlerFunc(pprof.Trace))	
---	
		go	func()	{	
					log.Println(http.ListenAndServe("localhost:6060",	mux));		
		}	
import	_	"net/http/pprof"	
go	func()	{	
		log.Println(http.ListenAndServe("localhost:6060",	nil))	
}()
github.com/pkg/profile
runtime/pprofをシンプルなインターフェースで提供
• shutdown signalのハンドリング
以下のプロファイラを利⽤可能
• CPU Profiler
• Heap Profiler
• Block Profiler
• Trace Profiler (runtime/trace)
package	main	
import	(	
		"github.com/pkg/profile"	
)	
func	main()	{	
		 defer	profile.Start(profile.BlockProfile).Stop()	
}
go test profiling
テストコードのプロファイリング
テストオプションに指定することによりプロファイリング可能
-blockprofile block.out : Block Profileの取得
-cpuprofile cpu.out : CPU Profileの取得
-memprofile mem.out : Heap Profileの取得
-mutexprofile mutex.out : Mutex Profileの取得
Go tool pprof
$	go	tool	pprof	--text	mpeg-probe	sample.prof/cpu.pprof	
108.45s	of	112.28s	total	(96.59%)	
Dropped	148	nodes	(cum	<=	0.56s)	
						flat		flat%			sum%								cum			cum%	
				78.03s	69.50%	69.50%					78.18s	69.63%		syscall.Syscall	
					8.47s		7.54%	77.04%						8.47s		7.54%		runtime.mach_semaphore_wait	
					7.19s		6.40%	83.44%						7.19s		6.40%		runtime.mach_semaphore_signal	
					3.43s		3.05%	86.50%						3.43s		3.05%		runtime.mach_semaphore_timedwait	
					3.02s		2.69%	89.19%						3.02s		2.69%		runtime.memclrNoHeapPointers
プロファイリングの集計・可視化
• `go tool pprof` を利⽤して
• コマンドラインでの実⾏と、インタラクティブシェルを提供
Go tool pprof
(pprof) web
• svg形式で吐き出されたプロファイルをwebブラウザで表⽰
• function名の指定で絞り込み
• graphvizのインストールが必要
$	go	tool	pprof		mpeg-probe	sample.prof/cpu.pprof	
Entering	interactive	mode	(type	"help"	for	commands)	
(pprof)	web	main
Go tool pprof
(pprof) top
• 取得したプロファイルの上位N件の表⽰
• `-FIELD` 指定によりソート
(pprof)	top	5	-flat	
100.14s	of	112.28s	total	(89.19%)	
Dropped	148	nodes	(cum	<=	0.56s)	
Showing	top	5	nodes	out	of	92	(cum	>=	3.02s)	
						flat		flat%			sum%								cum			cum%	
				78.03s	69.50%	69.50%					78.18s	69.63%		syscall.Syscall	
					8.47s		7.54%	77.04%						8.47s		7.54%		runtime.mach_semaphore_wait	
					7.19s		6.40%	83.44%						7.19s		6.40%		runtime.mach_semaphore_signal	
					3.43s		3.05%	86.50%						3.43s		3.05%		runtime.mach_semaphore_timedwait	
					3.02s		2.69%	89.19%						3.02s		2.69%		runtime.memclrNoHeapPointers
flat : 関数の使⽤した値
flat% : flat値の全体の占める割合
sum% : 現在のソート順でのflat値の累計値
cum : 関数の他の関数の呼び出しも含めた値
cum% : cum値の全体に占める割合
Go tool pprof
(pprof) list
• go tool実⾏時にバイナリファイルの指定が必要
• ソースコード上でのflat,cum値を表⽰
(pprof)	list	io.Copy	
Total:	1.87mins	
ROUTINE	========================	io.Copy	in	/usr/local/Cellar/go/1.8.1/libexec/src/io/io.go	
									0			1.09mins	(flat,	cum)	58.15%	of	Total	
									.										.				355://	If	src	implements	the	WriterTo	interface,	
									.										.				356://	the	copy	is	implemented	by	calling	src.WriteTo(dst).	
									.										.				357://	Otherwise,	if	dst	implements	the	ReaderFrom	interface,	
									.										.				358://	the	copy	is	implemented	by	calling	dst.ReadFrom(src).	
									.										.				359:func	Copy(dst	Writer,	src	Reader)	(written	int64,	err	error)	{	
									.			1.09mins				360:	 return	copyBuffer(dst,	src,	nil)	
									.										.				361:}	
									.										.				362:	
									.										.				363://	CopyBuffer	is	identical	to	Copy	except	that	it	stages	through	the	
									.										.				364://	provided	buffer	(if	one	is	required)	rather	than	allocating	a
Check Point
runtime.mallocgc
• メモリアロケーションが多く発⽣している
runtime.chanrecv, sync.Mutex
• ロック処理により多くの待ちが発⽣している
syscall Read / Write
• ioの読み書きが⼤量に発⽣している
GCコンポーネント
• ヒープサイズの⼩ささにより、GCの発⽣が頻繁に発⽣している
Go Debug Options
Memory Allocator Trace
- GODEBUG=allocfreetrace=1
Garbage Collector Trace
- GODEBUG=gctrace=1 .
Scheduler Trace
- GODEBUG=schedtrace=1000 ./

More Related Content

What's hot

What's hot (20)

コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話
 
Prometheus入門から運用まで徹底解説
Prometheus入門から運用まで徹底解説Prometheus入門から運用まで徹底解説
Prometheus入門から運用まで徹底解説
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
超実践 Cloud Spanner 設計講座
超実践 Cloud Spanner 設計講座超実践 Cloud Spanner 設計講座
超実践 Cloud Spanner 設計講座
 
TLS, HTTP/2演習
TLS, HTTP/2演習TLS, HTTP/2演習
TLS, HTTP/2演習
 
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
 
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線
 
PostgreSQL 12は ここがスゴイ! ~性能改善やpluggable storage engineなどの新機能を徹底解説~ (NTTデータ テクノ...
PostgreSQL 12は ここがスゴイ! ~性能改善やpluggable storage engineなどの新機能を徹底解説~ (NTTデータ テクノ...PostgreSQL 12は ここがスゴイ! ~性能改善やpluggable storage engineなどの新機能を徹底解説~ (NTTデータ テクノ...
PostgreSQL 12は ここがスゴイ! ~性能改善やpluggable storage engineなどの新機能を徹底解説~ (NTTデータ テクノ...
 
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
PostgreSQLのリカバリ超入門(もしくはWAL、CHECKPOINT、オンラインバックアップの仕組み)
PostgreSQLのリカバリ超入門(もしくはWAL、CHECKPOINT、オンラインバックアップの仕組み)PostgreSQLのリカバリ超入門(もしくはWAL、CHECKPOINT、オンラインバックアップの仕組み)
PostgreSQLのリカバリ超入門(もしくはWAL、CHECKPOINT、オンラインバックアップの仕組み)
 
Unified JVM Logging
Unified JVM LoggingUnified JVM Logging
Unified JVM Logging
 
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
 
OpenJDKのコミッタってどんなことしたらなったの?解決してきた技術課題の事例から見えてくる必要な知識と技術(JJUG CCC 2023 Spring)
OpenJDKのコミッタってどんなことしたらなったの?解決してきた技術課題の事例から見えてくる必要な知識と技術(JJUG CCC 2023 Spring)OpenJDKのコミッタってどんなことしたらなったの?解決してきた技術課題の事例から見えてくる必要な知識と技術(JJUG CCC 2023 Spring)
OpenJDKのコミッタってどんなことしたらなったの?解決してきた技術課題の事例から見えてくる必要な知識と技術(JJUG CCC 2023 Spring)
 
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
アーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーションアーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーション
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
Vacuum徹底解説
Vacuum徹底解説Vacuum徹底解説
Vacuum徹底解説
 

Similar to golang profiling の基礎

Similar to golang profiling の基礎 (20)

Programming camp Codereading
Programming camp CodereadingProgramming camp Codereading
Programming camp Codereading
 
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
 
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
 
Gocon2017:Goのロギング周りの考察
Gocon2017:Goのロギング周りの考察Gocon2017:Goのロギング周りの考察
Gocon2017:Goのロギング周りの考察
 
Pyconjp2014_implementations
Pyconjp2014_implementationsPyconjp2014_implementations
Pyconjp2014_implementations
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
Perl/CGI 入門
Perl/CGI 入門Perl/CGI 入門
Perl/CGI 入門
 
どこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティスどこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティス
 
78tch
78tch78tch
78tch
 
20130824 Lightweight Language "Go" @LL matsuri
20130824 Lightweight Language "Go" @LL matsuri20130824 Lightweight Language "Go" @LL matsuri
20130824 Lightweight Language "Go" @LL matsuri
 
JJUG CCC 20150411 grails3 Spring-boot
JJUG CCC 20150411 grails3 Spring-bootJJUG CCC 20150411 grails3 Spring-boot
JJUG CCC 20150411 grails3 Spring-boot
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
 
runC概要と使い方
runC概要と使い方runC概要と使い方
runC概要と使い方
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Next
 
UE4におけるLoadingとGCのProfilingと最適化手法
UE4におけるLoadingとGCのProfilingと最適化手法UE4におけるLoadingとGCのProfilingと最適化手法
UE4におけるLoadingとGCのProfilingと最適化手法
 
Drone programming with ArduPilot
Drone programming  with ArduPilotDrone programming  with ArduPilot
Drone programming with ArduPilot
 
Ocamlでpfffを拡張した話
Ocamlでpfffを拡張した話Ocamlでpfffを拡張した話
Ocamlでpfffを拡張した話
 
Pythonによる非同期プログラミング入門
Pythonによる非同期プログラミング入門Pythonによる非同期プログラミング入門
Pythonによる非同期プログラミング入門
 
Project Sumatra - JavaOne2012報告会 #j1rep
Project Sumatra - JavaOne2012報告会 #j1repProject Sumatra - JavaOne2012報告会 #j1rep
Project Sumatra - JavaOne2012報告会 #j1rep
 

golang profiling の基礎