A little weird thing in using finalizer

85 views
Skip to first unread message

T L

unread,
Apr 25, 2020, 12:30:05 AM4/25/20
to golang-nuts
The following program might print:

31
37
47
47
37
31

or

31
37
47
47

but with the highest possibility to print

31
37
47

Is not normal?


package main

import (
    "fmt"
    "math/rand"
    "runtime"
    "time"
    "unsafe"
)

type Foo struct {
    x int
    a int
}

func main() {
    for i := 0; i < 3; i++ {
        f := NewFoo(i)
        println(f.a)
    }

    runtime.GC()
   
    time.After(time.Second)
}

func do(i *uint) {
    runtime.SetFinalizer(i, func(f *uint) {
        fmt.Println(*f)
    })
}

//go:noinline
func NewFoo(i int) *Foo {
    f := &Foo{a: rand.Intn(50)}
   
    do((*uint)(unsafe.Pointer(&f.a)))

    return f
}

Ian Lance Taylor

unread,
Apr 25, 2020, 1:08:43 AM4/25/20
to T L, golang-nuts
Finalizers are not guaranteed to run.

That said, I'm not sure why you are calling time.After. That doesn't
make finalizers any more likely to run. You'll probably see fairly
reliable results if you change that to call time.Sleep instead.

Ian

T L

unread,
Apr 25, 2020, 1:35:22 AM4/25/20
to golang-nuts
With time.Sleep, it always prints:
31
37
47
47
37
31

Why is each of the finalizers called twice?

Brian Candler

unread,
Apr 25, 2020, 1:53:28 AM4/25/20
to golang-nuts
On Saturday, 25 April 2020 06:35:22 UTC+1, T L wrote:
Why is each of the finalizers called twice?


Isn't it just printed once in main and once in finalizer?

T L

unread,
Apr 25, 2020, 2:49:54 AM4/25/20
to golang-nuts
Aha, I'm sorry I forgot that println line. I thought all the lines are printed in finalizers. ;D
Reply all
Reply to author
Forward
0 new messages