
测试一
新建一个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,造成资源的浪费。
网友评论