github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/testutils/pprof.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package testutils 12 13 import ( 14 "os" 15 "runtime" 16 "runtime/pprof" 17 "testing" 18 ) 19 20 // WriteProfile serialized the pprof profile with the given name to a file at 21 // the given path. 22 func WriteProfile(t testing.TB, name string, path string) { 23 f, err := os.Create(path) 24 if err != nil { 25 t.Fatal(err) 26 } 27 defer f.Close() 28 if err := pprof.Lookup(name).WriteTo(f, 0); err != nil { 29 t.Fatal(err) 30 } 31 } 32 33 // AllocProfileDiff writes two alloc profiles, one before running closure and 34 // one after. This is similar in spirit to passing the -memprofile flag to a 35 // test or benchmark, but make it possible to subtract out setup code, which 36 // -memprofile does not. 37 // 38 // Example usage: 39 // setupCode() 40 // AllocProfileDiff(t, "mem.before", "mem.after", func() { 41 // interestingCode() 42 // }) 43 // 44 // The resulting profiles are then diffed via: 45 // go tool pprof -base mem.before mem.after 46 func AllocProfileDiff(t testing.TB, beforePath, afterPath string, fn func()) { 47 // Use "allocs" instead of "heap" to match what -memprofile does. Also run 48 // runtime.GC immediately before grabbing the profile because the allocs 49 // profile is materialized on gc, so this makes sure we have the latest data. 50 // 51 // https://github.com/golang/go/blob/go1.12.4/src/testing/testing.go#L1264-L1269 52 runtime.GC() 53 WriteProfile(t, "allocs", beforePath) 54 fn() 55 runtime.GC() 56 WriteProfile(t, "allocs", afterPath) 57 t.Logf("to use your alloc profiles: go tool pprof -base %s %s", beforePath, afterPath) 58 } 59 60 // Make the unused linter happy. 61 var _ = WriteProfile 62 var _ = AllocProfileDiff