美文网首页
Go:M什么时候会被回收?

Go:M什么时候会被回收?

作者: 沙漠中的猴 | 来源:发表于2018-10-23 15:05 被阅读0次

测试一

新建一个main.go文件。将下面的代码写入。

package main

import (
    "runtime"
    "sync/atomic"
    "time"
)

var count int64

func test() {
    atomic.AddInt64(&count, 1)
    defer atomic.AddInt64(&count, -1)

    runtime.LockOSThread()
    defer runtime.UnlockOSThread()

    time.Sleep(time.Second)
}

func main() {
    for i := 0; i < 2000; i++ {
        go test()
    }

    for {
        time.Sleep(time.Second)
    }
}

使用GODEBUG命令来执行程序

go build -o main main.go && GODEBUG=schedtrace=1000 ./main

会得到如下内容:

00d3fada0b3:~/go/src# go build -o main main.go && GODEBUG=schedtrace=1000 ./main
SCHED 0ms: gomaxprocs=2 idleprocs=0 threads=4 spinningthreads=1 idlethreads=0 runqueue=0 [128 9]
SCHED 1009ms: gomaxprocs=2 idleprocs=1 threads=2008 spinningthreads=0 idlethreads=257 runqueue=0 [0 0]
SCHED 2014ms: gomaxprocs=2 idleprocs=2 threads=2008 spinningthreads=0 idlethreads=2005 runqueue=0 [0 0]
SCHED 3015ms: gomaxprocs=2 idleprocs=2 threads=2008 spinningthreads=0 idlethreads=2005 runqueue=0 [0 0]
SCHED 4027ms: gomaxprocs=2 idleprocs=2 threads=2008 spinningthreads=0 idlethreads=2005 runqueue=0 [0 0]
SCHED 5038ms: gomaxprocs=2 idleprocs=2 threads=2008 spinningthreads=0 idlethreads=2005 runqueue=0 [0 0]
SCHED 6039ms: gomaxprocs=2 idleprocs=2 threads=2008 spinningthreads=0 idlethreads=2005 runqueue=0 [0 0]
SCHED 7042ms: gomaxprocs=2 idleprocs=2 threads=2008 spinningthreads=0 idlethreads=2005 runqueue=0 [0 0]
SCHED 8045ms: gomaxprocs=2 idleprocs=2 threads=2008 spinningthreads=0 idlethreads=2005 runqueue=0 [0 0]

可以看到当前的P(调度器)有两个,都处于idle状态。M总共有2008个,其中2005个处于idle状态。 这就说明空闲状态的M,并没有被回收。

测试二:

将上面的代码中defer runtime.UnlockOSThread()注释掉,造成M死锁状态。然后重新执行代码。

go build -o main main.go && GODEBUG=schedtrace=1000 ./main

会得到如下内容:

00d3fada0b3:~/go/src# go build -o main main.go && GODEBUG=schedtrace=1000 .
SCHED 0ms: gomaxprocs=2 idleprocs=0 threads=4 spinningthreads=1 idlethreads=0 runqueue=0 [0 0]
SCHED 1005ms: gomaxprocs=2 idleprocs=0 threads=1982 spinningthreads=0 idlethreads=2 runqueue=0 [19 9]
SCHED 2010ms: gomaxprocs=2 idleprocs=2 threads=11 spinningthreads=0 idlethreads=8 runqueue=0 [0 0]
SCHED 3020ms: gomaxprocs=2 idleprocs=2 threads=11 spinningthreads=0 idlethreads=8 runqueue=0 [0 0]
SCHED 4030ms: gomaxprocs=2 idleprocs=2 threads=11 spinningthreads=0 idlethreads=8 runqueue=0 [0 0]
SCHED 5030ms: gomaxprocs=2 idleprocs=2 threads=11 spinningthreads=0 idlethreads=8 runqueue=0 [0 0]
SCHED 6031ms: gomaxprocs=2 idleprocs=2 threads=11 spinningthreads=0 idlethreads=8 runqueue=0 [0 0]

可以看到存在的M要比之前少了很多。大部分的M都被回收了。

总结

M出问题的时候才会被回收,否则一直存在。

在我们写代码的时候,应注意一下不要重复创建太多的M,造成资源的浪费。

相关文章

  • Go:M什么时候会被回收?

    测试一 新建一个main.go文件。将下面的代码写入。 使用GODEBUG命令来执行程序 会得到如下内容: 可以看...

  • Go语言——垃圾回收GC

    Go语言——垃圾回收GC 参考: Go 垃圾回收原理 Golang源码探索(三) GC的实现原理 Getting ...

  • 图片三级缓存的原理(项目经验)

    补充的知识:强引用:不会被回收弱引用:垃圾回收器触发会被回收软引用:系统检测内存不足时会被回收虚引用:等于null...

  • 现代的垃圾回收机制(Go 垃圾回收机制概述)

    现代的垃圾回收机制(Go 垃圾回收机制概述) 关于 Go GC策略的见解 细节你可以到 Hacker News 和...

  • Java高阶知识点

    哪些情况下的对象会被垃圾回收机制处理掉?Java GC机制主要完成3件事:确定哪些内存需要回收,确定什么时候需要执...

  • Golang之GC

    参考 图解Golang的GC算法 搞懂Go垃圾回收 Golang垃圾回收 屏障技术

  • 强引用、软引用、弱引用

    强引用:永远不会被垃圾回收器回收,宁可抛出OOM软引用:在内存足够的情况下,不会被垃圾回收器回收。当内存不够的情况...

  • java单例

    单例不会被回收

  • 浅谈Golang垃圾回收

    众所周知,Go 是一门自带垃圾回收的语言,那么 Go 的 GC 是怎么实现的,和其他的自带垃圾回收的语言又有什么区...

  • 强引用,弱引用,软引用,虚引用。

    强引用,最常用,最简单的。A a = new A()不会被垃圾回收机制回收,只有a=null 才会被销毁。 软引用...

网友评论

      本文标题:Go:M什么时候会被回收?

      本文链接:https://www.haomeiwen.com/subject/utkazftx.html