请教:以下测试 SetFinalizer 用例在通过时间触发 GC 的情况下不生效

richardweiu · · 2059 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

- 问题:以下测试代码验证 SetFinalizer 中,通过时间触发 GC 的情况下不生效 - 说明: - 预期:触发 GC,由 GC 执行 Finalizer 方法 - 测试通过执行 `runtime.GC()` 方法手动触发 GC 符合预期 - 测试通过 `buf := make([]byte, 1024*1024*1024*10)` 触发 gcTriggerHeap 条件也能够符合预期 - 打开 `GODEBUG=gctrace=1`,通过 sleep 两次 120s(利用 gcTriggerTime 触发 GC),确实也看到 GC 触发的打印输出,但是却并没有执行注册好的 Finalizer 方法 ```golang 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") // 手动调用可以触发 Finalizer // runtime.GC() // 内存提升到阈值也是可以触发 // buf := make([]byte, 1024*1024*1024*10) // buf[0] = 1 time.Sleep(time.Second * 60) fmt.Println("wait 60") time.Sleep(time.Second * 61) // 预期这里两分钟触发了 GC, 应该会调用dog_stop,为啥没有呢 fmt.Println("wait 60") time.Sleep(time.Second * 60) fmt.Println("wait 60") time.Sleep(time.Second * 70) fmt.Println("wait 70") } ``` 这是第二个 60s 触发 GC 时候的截图(也就是第一个 120s) ![image.png](https://static.studygolang.com/210623/72482e56d2d864abf488468aa360b0b1.png) 这是第四个 60s 触发 GC 时候的截图(也就是第2个 120s) ![image.png](https://static.studygolang.com/210623/5c907383d2409e04d0a16a162c70e688.png)

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2059 次点击  
加入收藏 微博
2 回复  |  直到 2021-06-24 12:07:21
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传