funcmapPointer(num int) { m := make(map[int]*int, num) for i := 0; i < num; i++ { m[i] = &i } runtime.GC() fmt.Printf("With %T, GC took %s\n", m, timeGC()) _ = m[0] }
funcmapValue(num int) { m := make(map[int]int, num) for i := 0; i < num; i++ { m[i] = i } runtime.GC() fmt.Printf("With %T, GC took %s\n", m, timeGC()) _ = m[0] }
funcmapPointerShard(num int) { shards := make([]map[int]*int, 100) for i := range shards { shards[i] = make(map[int]*int) } for i := 0; i < num; i++ { shards[i%100][i] = &i } runtime.GC() fmt.Printf("With map shards (%T), GC took %s\n", shards, timeGC()) _ = shards[0][0] }
funcmapValueShard(num int) { shards := make([]map[int]int, 100) for i := range shards { shards[i] = make(map[int]int) } for i := 0; i < num; i++ { shards[i%100][i] = i } runtime.GC() fmt.Printf("With map shards (%T), GC took %s\n", shards, timeGC()) _ = shards[0][0] }
$ go test -bench=^BenchmarkMapPointer$ -benchmem With map[int]*int, GC took 545.139836ms goos: darwin goarch: amd64 pkg: com.learn/gormLearn/gc_gc BenchmarkMapPointer-4 1 9532798100 ns/op 1387850488 B/op 724960 allocs/op
$ go test -bench=^BenchmarkMapPointerShard$ -benchmem With map shards ([]map[int]*int), GC took 688.39764ms goos: darwin goarch: amd64 pkg: com.learn/gormLearn/gc_gc BenchmarkMapPointerShard-4 1 20670458639 ns/op 4286763416 B/op 1901279 allocs/op
$ go test -bench=^BenchmarkMapValueShard$ -benchmem With map shards ([]map[int]int), GC took 1.965519ms goos: darwin goarch: amd64 pkg: com.learn/gormLearn/gc_gc BenchmarkMapValueShard-4 1 16190847776 ns/op 4385268936 B/op 1918445 allocs/op
$ go test -bench=^BenchmarkMapValue$ -benchmem With map[int]int, GC took 22.993926ms goos: darwin goarch: amd64 pkg: com.learn/gormLearn/gc_gc BenchmarkMapValue-4 1 8253025035 ns/op 1444338752 B/op 724512 allocs/op
$ GODEBUG=gctrace=1 go test -bench=^BenchmarkMapPointer$ -benchmem ... gc 3 @0.130s 19%: 0.006+424+0.013 ms clock, 0.027+0.18/424/848+0.055 ms cpu, 1224->1224->1224 MB, 1225 MB goal, 4 P gc 4 @9.410s 2%: 0.005+543+0.002 ms clock, 0.022+0/543/1628+0.011 ms cpu, 1325->1325->1323 MB, 2448 MB goal, 4 P (forced) gc 5 @9.957s 3%: 0.003+547+0.003 ms clock, 0.013+0/547/1631+0.013 ms cpu, 1323->1323->1323 MB, 2647 MB goal, 4 P (forced) With map[int]*int, GC took 550.40821ms
为了理解打印的日志,我们要理解gctrace, 以0.013+0/547/1631+0.013 ms cpu为例子,GC分为三个阶段。
Mark Prepare (STW) 。0.013表示标记阶段的全局暂停(stop the wrold)时间。