Home | History | Annotate | Download | only in garbage
      1 // Copyright 2012 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package main
      6 
      7 import (
      8 	"flag"
      9 	"fmt"
     10 	"log"
     11 	"os"
     12 	"runtime"
     13 	"runtime/pprof"
     14 	"time"
     15 	"unsafe"
     16 )
     17 
     18 const BranchingFactor = 4
     19 
     20 type Object struct {
     21 	child [BranchingFactor]*Object
     22 }
     23 
     24 var (
     25 	cpus       = flag.Int("cpus", 1, "number of cpus to use")
     26 	heapsize   = flag.Int64("heapsize", 100*1024*1024, "size of the heap in bytes")
     27 	cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
     28 
     29 	lastPauseNs uint64 = 0
     30 	lastFree    uint64 = 0
     31 	heap        *Object
     32 	calls       [20]int
     33 	numobjects  int64
     34 	memstats    runtime.MemStats
     35 )
     36 
     37 func buildHeap() {
     38 	objsize := int64(unsafe.Sizeof(Object{}))
     39 	heap, _ = buildTree(float64(objsize), float64(*heapsize), 0)
     40 	fmt.Printf("*** built heap: %.0f MB; (%d objects * %d bytes)\n",
     41 		float64(*heapsize)/1048576, numobjects, objsize)
     42 }
     43 
     44 func buildTree(objsize, size float64, depth int) (*Object, float64) {
     45 	calls[depth]++
     46 	x := &Object{}
     47 	numobjects++
     48 	subtreeSize := (size - objsize) / BranchingFactor
     49 	alloc := objsize
     50 	for i := 0; i < BranchingFactor && alloc < size; i++ {
     51 		c, n := buildTree(objsize, subtreeSize, depth+1)
     52 		x.child[i] = c
     53 		alloc += n
     54 	}
     55 	return x, alloc
     56 }
     57 
     58 func gc() {
     59 	runtime.GC()
     60 	runtime.ReadMemStats(&memstats)
     61 	pause := memstats.PauseTotalNs
     62 	inuse := memstats.Alloc
     63 	free := memstats.TotalAlloc - inuse
     64 	fmt.Printf("gc pause: %8.3f ms; collect: %8.0f MB; heapsize: %8.0f MB\n",
     65 		float64(pause-lastPauseNs)/1e6,
     66 		float64(free-lastFree)/1048576,
     67 		float64(inuse)/1048576)
     68 	lastPauseNs = pause
     69 	lastFree = free
     70 }
     71 
     72 func main() {
     73 	flag.Parse()
     74 	buildHeap()
     75 	runtime.GOMAXPROCS(*cpus)
     76 	runtime.ReadMemStats(&memstats)
     77 	lastPauseNs = memstats.PauseTotalNs
     78 	lastFree = memstats.TotalAlloc - memstats.Alloc
     79 	if *cpuprofile != "" {
     80 		f, err := os.Create(*cpuprofile)
     81 		if err != nil {
     82 			log.Fatal(err)
     83 		}
     84 		pprof.StartCPUProfile(f)
     85 		defer pprof.StopCPUProfile()
     86 	}
     87 	const N = 10
     88 	var t0 time.Time
     89 	for i := 0; i < N; i++ {
     90 		t0 = time.Now()
     91 		gc()
     92 	}
     93 	// Standard gotest benchmark output, collected by build dashboard.
     94 	gcstats("BenchmarkTree2", N, time.Now().Sub(t0))
     95 }
     96