gogctuner
gogctuner copied to clipboard
What's the use of finalizer.ch?
Avoid finalizer being collected by GC? why use chan time.Time?
Avoid finalizer being collected by GC? why use chan time.Time?
the original code is from uber's blog article, I think any struct is ok~
can it just simply be runtime.KeepAlive(f.parent) or just be empty (do nothing)?
Thanks guys, I have done some experiments after your questions, I think this channel is useless, you can reproduce the result by following demo:
package main
import (
"runtime"
"time"
)
type finalizer struct {
ref *finalizerRef
}
type finalizerRef struct {
parent *finalizer
}
// default GOGC = 100
var previousGOGC = 100
// don't trigger err log on every failure
var failCounter = -1
func finalizerHandler(f *finalizerRef) {
println("in final handler")
runtime.SetFinalizer(f, finalizerHandler)
}
type person struct {
data []byte
}
// NewTuner
// set useCgroup to true if your app is in docker
// set percent to control the gc trigger, 0-100, 100 or upper means no limit
//
// modify default GOGC value in the case there's an env variable set.
func getFinal() * finalizer {
var f = &finalizer{
}
f.ref = &finalizerRef{parent: f}
runtime.SetFinalizer(f.ref, finalizerHandler)
f.ref = nil
return f
}
func main() {
f := getFinal()
println(f)
for {
var x = person{make([]byte, 100000)}
time.Sleep(time.Millisecond*40)
println(x.data[0])
}
}
GODEBUG=gctrace=1 go run ./tuner.go
you should see every gc trigger will print a line of 'in final handler'