0

runtime.GC() and gcTriggerHeap trigger will meet expectations, but It does not call Finalizer function when I use gcTriggerTime(sleep 120s)

like this: (the second 60s) enter image description here (the fourth 60s) enter image description here

the code is:

package main

import (
    "fmt"
    "runtime"
    "time"
)

type dog struct {
    stop chan bool
}

func (d *dog) dog_run() {
    ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()
    for {
        select {
        case <-ticker.C:
            fmt.Println("bark")
        case <-d.stop:
            fmt.Println("stop!!!!!!!!!")
            return
        }
    }
}

type School struct {
    Students []string
    dog      *dog
}

func dog_stop(s *School) {
    s.dog.stop <- true
}

func (s *School) new() {
    watch_dog := dog{
        stop: make(chan bool, 1),
    }
    s.dog = &watch_dog
    go watch_dog.dog_run()
}

func NewSchool(names ...string) *School {
    school := School{Students: names}
    school.new()
    runtime.SetFinalizer(&school, dog_stop)
    return &school
}

func main() {
    school := NewSchool([]string{"pd"}...)
    fmt.Println("start school", school)
    time.Sleep(time.Second * 4)
    school = nil
    fmt.Println("closed school")
    // manual GC it does work
    // runtime.GC()

    // auto GC use gcTriggerHeap, it does work
    // buf := make([]byte, 1024*1024*1024*10)
    // buf[0] = 1

    time.Sleep(time.Second * 60)
    fmt.Println("wait 60")
    time.Sleep(time.Second * 61) // it triger GC, should use dog_stop,but why not
    fmt.Println("wait 60")
    time.Sleep(time.Second * 60)
    fmt.Println("wait 60")
    time.Sleep(time.Second * 70)
    fmt.Println("wait 70")
}

richard
  • 49
  • 6
  • 2
    What do you think is supposed to happen, and why? – Hymns For Disco Jun 24 '21 at 16:52
  • 3
    ["The finalizer is scheduled to run at some arbitrary time after the program can no longer reach the object to which obj points. There is no guarantee that finalizers will run before a program exits"](https://golang.org/pkg/runtime/#SetFinalizer) – Adrian Jun 24 '21 at 17:02
  • 1
    Just in case of us dealing with [an XY Problem](https://meta.stackexchange.com/questions/66377/), if you are after "destructors" in Go, please don't: Go has a different idiom for cleaning up state, and [for a reason](https://stackoverflow.com/a/32781054/720999). – kostix Jun 24 '21 at 17:35

0 Answers0