概要
メモリ使用量を取得するやり方を調べていたので、忘れないうちにメモメモ。
大抵どの言語でもあるものなんですが、Goの場合は runtime.ReadMemStats(*runtime.MemStats)
で取得できるみたいですね。
以下、ちょっとしたメモ書きサンプルです。
サンプル
package runtime_ import ( "context" "fmt" "github.com/devlights/try-golang/lib/output" "runtime" "sync" "time" ) // RuntimeMemoryStats は、runtime.MemoryStats() のサンプルです. // // REFERENCES:: // - https://golangcode.com/print-the-current-memory-usage/ func RuntimeMemoryStats() error { var ( rootCtx = context.Background() mainCtx, cancel = context.WithCancel(rootCtx) wg = &sync.WaitGroup{} ) // 初期の状態を表示 runtime.GC() printMemoryStats("init") // --------------------------------------- // データを500ミリ秒毎に増やしていく処理 // --------------------------------------- wg.Add(1) go func(ctx context.Context, wg *sync.WaitGroup) { var ( tick = time.Tick(500 * time.Millisecond) count = 0 items = make([][]byte, 0, 5) ) defer wg.Done() for { select { case <-ctx.Done(): return case _ = <-tick: count++ data := make([]byte, 0, 1024*1024) items = append(items, data) // output.Stderrf("[append]", "count=%d\ttick=%v\n", count, t) } } }(mainCtx, wg) // --------------------------------------- // 現在のメモリ量を2000ミリ秒毎に出力する処理 // --------------------------------------- wg.Add(1) go func(ctx context.Context, wg *sync.WaitGroup) { var ( tick = time.Tick(2000 * time.Millisecond) count = 0 ) defer wg.Done() for { select { case <-ctx.Done(): return case <-tick: count++ printMemoryStats(fmt.Sprintf("(%d)", count)) } } }(mainCtx, wg) // 10秒したら終わり select { case <-time.After(10 * time.Second): cancel() wg.Wait() } // 最後の状態を表示 printMemoryStats("latest") // GC後の状態を表示 runtime.GC() printMemoryStats("after runtime.GC()") return nil } func printMemoryStats(prefix string) { // -------------------------------------------------------- // runtime.MemoryStats() から、現在の割当メモリ量などが取得できる. // // まず、データの受け皿となる runtime.MemStats を初期化し // runtime.ReadMemStats(*runtime.MemStats) を呼び出して // 取得する. // -------------------------------------------------------- var ( ms runtime.MemStats ) output.Stdoutl(prefix, "----------------------------") runtime.ReadMemStats(&ms) // Alloc は、現在ヒープに割り当てられているメモリ // HeapAlloc と同じ. output.Stdoutl("Alloc", toKb(ms.Alloc)) output.Stdoutl("HeapAlloc", toKb(ms.HeapAlloc)) // TotalAlloc は、ヒープに割り当てられたメモリ量の累積 // Allocと違い、こちらは増えていくが減ることはない output.Stdoutl("TotalAlloc", toKb(ms.TotalAlloc)) // HeapObjects は、ヒープに割り当てられているオブジェクトの数 output.Stdoutl("HeapObjects", toKb(ms.HeapObjects)) // Sys は、OSから割り当てられたメモリの合計量 output.Stdoutl("Sys", toKb(ms.Sys)) // NumGC は、実施されたGCの回数 output.Stdoutl("NumGC", ms.NumGC) } func toKb(bytes uint64) uint64 { return bytes / 1024 } //noinspection GoUnusedFunction func toMb(bytes uint64) uint64 { return toKb(bytes) / 1024 }
try-golang/runtime_memorystats.go at master · devlights/try-golang · GitHub
実行すると以下のようになります。
$ make run ENTER EXAMPLE NAME: runtime_mem [Name] "runtime_memorystats" init ---------------------------- Alloc 190 HeapAlloc 190 TotalAlloc 241 HeapObjects 1 Sys 4932 NumGC 1 (1) ---------------------------- Alloc 3269 HeapAlloc 3269 TotalAlloc 3320 HeapObjects 1 Sys 10822 NumGC 1 (2) ---------------------------- Alloc 8390 HeapAlloc 8390 TotalAlloc 8444 HeapObjects 1 Sys 15114 NumGC 3 (3) ---------------------------- Alloc 11463 HeapAlloc 11463 TotalAlloc 11518 HeapObjects 1 Sys 19342 NumGC 3 (4) ---------------------------- Alloc 16584 HeapAlloc 16584 TotalAlloc 16638 HeapObjects 1 Sys 23570 NumGC 3 (5) ---------------------------- Alloc 20679 HeapAlloc 20679 TotalAlloc 20736 HeapObjects 1 Sys 27798 NumGC 4 latest ---------------------------- Alloc 20679 HeapAlloc 20679 TotalAlloc 20736 HeapObjects 1 Sys 27798 NumGC 4 after runtime.GC() ---------------------------- Alloc 197 HeapAlloc 197 TotalAlloc 20738 HeapObjects 1 Sys 27798 NumGC 5
参考
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場