package main

import (
	"fmt"
	"runtime"
	"runtime/debug"
)

const count = 10000

var tiny []*[1]byte
var small []*[17]byte
var next []*[33]byte

func report(label string, a, b runtime.MemStats) {
	fmt.Printf("%s: objects=%d bytes=%d\n", label, b.Mallocs-a.Mallocs, b.TotalAlloc-a.TotalAlloc)
	for i := range a.BySize {
		if n := b.BySize[i].Mallocs - a.BySize[i].Mallocs; n > 0 {
			fmt.Printf("  class=%d count=%d\n", b.BySize[i].Size, n)
		}
	}
}

func main() {
	old := debug.SetGCPercent(-1)
	defer debug.SetGCPercent(old)
	tiny = make([]*[1]byte, count)
	small = make([]*[17]byte, count)
	next = make([]*[33]byte, count)
	var a, b, c, d runtime.MemStats
	runtime.ReadMemStats(&a)
	for i := range tiny {
		tiny[i] = new([1]byte)
	}
	runtime.ReadMemStats(&b)
	for i := range small {
		small[i] = new([17]byte)
	}
	runtime.ReadMemStats(&c)
	for i := range next {
		next[i] = new([33]byte)
	}
	runtime.ReadMemStats(&d)
	report("1 byte", a, b)
	report("17 bytes", b, c)
	report("33 bytes", c, d)
	runtime.KeepAlive(tiny)
	runtime.KeepAlive(small)
	runtime.KeepAlive(next)
}
