runtime.SetFinalizerを使って値ごとのデバッグプリント関数を仕込むことでGCされたときにデバッグログを残すテクニックを教えてもらったのでメモしておく。

package main

import (
	"bytes"
	"fmt"
	"runtime"
)

func main() {
	buf := bytes.NewBuffer(nil)
	runtime.SetFinalizer(buf, func(v interface{}) {
		fmt.Printf("disposed: %T\n", v)
	})
	runtime.GC()
}

みたいな感じで確認できる(Playground)。ただし上記サンプルだとすぐにプログラムが終了する都合上、実行ごとにログが出たり出なかったり結果が安定しなかった。ファイナライザーの実行は別Goroutineで実行されるとのことなのでそのへんはやむなし。