それはあなたのためのカウントを行いruntime.SetFinalizer
にラッパーを作成することが可能です。もちろん、それはどこでもあなたが使うSetFinalizer
を使用することの問題です。
問題がある場合はSetFinalizer
ソースコードを直接変更することもできますが、それにはa modified Go compilerが必要です。
アトミック整数は、異なるスレッドで呼び出される可能性があります。そうしないと、競合状態が発生する可能性がないため、カウンタが正確でない可能性があります。 Golangは、ファイナライザが単一のゴルーチンから呼び出されることを保証しているため、内部関数には必要ありません。
https://play.golang.org/p/KKCH2UwTFYw
package main
import (
"fmt"
"reflect"
"runtime"
"sync/atomic"
)
var finalizersCreated int64
var finalizersRan int64
func SetFinalizer(obj interface{}, finalizer interface{}) {
finType := reflect.TypeOf(finalizer)
funcType := reflect.FuncOf([]reflect.Type{finType.In(0)}, nil, false)
f := reflect.MakeFunc(funcType, func(args []reflect.Value) []reflect.Value {
finalizersRan++
return reflect.ValueOf(finalizer).Call([]reflect.Value{args[0]})
})
runtime.SetFinalizer(obj, f.Interface())
atomic.AddInt64(&finalizersCreated, 1)
}
func main() {
v := "a"
SetFinalizer(&v, func(a *string) {
fmt.Println("Finalizer ran")
})
fmt.Println(finalizersRan, finalizersCreated)
runtime.GC()
fmt.Println(finalizersRan, finalizersCreated)
}
私が関与するすべてのソースにパッチを適用することはできませんので、私は、ランタイム自体にこれを入れなければならないだろうと思います。しかしファイナライザの登録を解除することは可能ですので、カウントは重要ではありません。私はランタイム自体からカウンターを集めるための何らかの方法を望んでいました。 –