Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's the use of finalizer.ch? #6

Open
yanxyc opened this issue Apr 7, 2022 · 3 comments
Open

What's the use of finalizer.ch? #6

yanxyc opened this issue Apr 7, 2022 · 3 comments

Comments

@yanxyc
Copy link

yanxyc commented Apr 7, 2022

Avoid finalizer being collected by GC? why use chan time.Time?

@cch123
Copy link
Owner

cch123 commented Apr 9, 2022

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~

@zjx20
Copy link

zjx20 commented Apr 24, 2022

can it just simply be runtime.KeepAlive(f.parent) or just be empty (do nothing)?

@cch123
Copy link
Owner

cch123 commented May 5, 2022

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'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants