]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: record per-phase memory profile
authorAustin Clements <austin@google.com>
Fri, 20 Mar 2020 19:52:43 +0000 (15:52 -0400)
committerAustin Clements <austin@google.com>
Sat, 21 Mar 2020 13:48:35 +0000 (13:48 +0000)
We already have an option to record per-phase CPU profiles. If we're
in "mem" benchmark mode, then it also makes sense to collect a heap
profile of the live heap at the end of a phase. This CL adds that
profile and changes the extensions of the profiles to "cpuprof" and
"memprof" to make the distinction clear.

Change-Id: Ia05b7fa18bccad954a875f7a55d9cff5ad8dfaaf
Reviewed-on: https://go-review.googlesource.com/c/go/+/224617
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/link/internal/benchmark/bench.go
src/cmd/link/internal/benchmark/bench_test.go

index 52f98269a14d6e49a7c0b1a29ef7a746fbb62759..7b8492ec85f9d68783c2f65c74ef3a9df3acda72 100644 (file)
@@ -116,7 +116,7 @@ func (m *Metrics) Start(name string) {
        m.curMark = &mark{name: name}
        // Unlikely we need to a GC here, as one was likely just done in closeMark.
        if m.shouldPProf() {
-               f, err := os.Create(makePProfFilename(m.filebase, name))
+               f, err := os.Create(makePProfFilename(m.filebase, name, "cpuprof"))
                if err != nil {
                        panic(err)
                }
@@ -143,6 +143,25 @@ func (m *Metrics) closeMark() {
                pprof.StopCPUProfile()
                m.pprofFile.Close()
                m.pprofFile = nil
+               if m.gc == GC {
+                       // Collect a profile of the live heap. Do a
+                       // second GC to force sweep completion so we
+                       // get a complete snapshot of the live heap at
+                       // the end of this phase.
+                       runtime.GC()
+                       f, err := os.Create(makePProfFilename(m.filebase, m.curMark.name, "memprof"))
+                       if err != nil {
+                               panic(err)
+                       }
+                       err = pprof.WriteHeapProfile(f)
+                       if err != nil {
+                               panic(err)
+                       }
+                       err = f.Close()
+                       if err != nil {
+                               panic(err)
+                       }
+               }
        }
        m.marks = append(m.marks, m.curMark)
        m.curMark = nil
@@ -171,6 +190,6 @@ func makeBenchString(name string) string {
        return string(ret)
 }
 
-func makePProfFilename(filebase, name string) string {
-       return fmt.Sprintf("%s_%s.profile", filebase, makeBenchString(name))
+func makePProfFilename(filebase, name, typ string) string {
+       return fmt.Sprintf("%s_%s.%s", filebase, makeBenchString(name), typ)
 }
index 48d4d74046fde64d67a85a7e774745685fe63fe5..d8ec717c7c08d547d4094fb1953c9d4a1d1b2a39 100644 (file)
@@ -39,8 +39,8 @@ func TestPProfFlag(t *testing.T) {
 }
 
 func TestPProfNames(t *testing.T) {
-       want := "foo_BenchmarkTest.profile"
-       if v := makePProfFilename("foo", "test"); v != want {
+       want := "foo_BenchmarkTest.cpuprof"
+       if v := makePProfFilename("foo", "test", "cpuprof"); v != want {
                t.Errorf("makePProfFilename() == %q, want %q", v, want)
        }
 }