美文网首页
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什么时候会被回收?

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