简介
GODEBUG 环境变量可以控制程序运行时的调度信息输出,方便开发者了解内部细节。
语法是通过逗号分割多个键值对,例如:
# 运行 main.go, 每秒输出 1 次调度信息
$ GODEBUG=scheddetail=1,schedtrace=1000 go run main.go
常用参数
名称 | 值 | 描述 |
---|---|---|
scheddetail | 1 | 设置 schedtrace=X 和 scheddetail=1, 每 X 毫秒输出 1 次调度信息 |
schedtrace | X | 每 X 毫秒输出 1 次调度信息 |
allocfreetrace | 1 | 监控每次分配,分析和打印每个对象的分配和释放的调用堆栈 |
cgocheck | [0, 1, 2] | CGO 是否检查 Go 指针传递给非 Go 代码, 0: 禁用 1: 弱检查 2: 强检查 |
efence | 1 | 让分配器把每个对象都分配在一个唯一的从未回收的页面 |
gccheckmark | 1 | 启用 GC 执行并发标记 |
gcpacertrace | 1 | 打印并发 pacer 的内部状态 |
gcshrinkstackoff | 1 | 禁用移动 goroutines 到较小的栈上,在这种模式下,goroutine 的栈只能增长 |
gcstoptheworld | 1 | 禁用并发 GC,每次 GC 都会触发 STW |
gctrace | 1 | 每次 GC 时输出一行日志,统计内存回收和暂停时间 |
memprofilerate | [0, X] | 0: 禁用 X: 更新 runtime.MemProfileRate 的值 |
示例程序
本文后面的几个用例,全部使用该程序演示。
package main
import (
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(1 * time.Second)
}()
}
wg.Wait()
}
输出调度基础信息
执行命令
$ GODEBUG=schedtrace=1000 go run main.go
# 输出如下
SCHED 0ms: gomaxprocs=8 idleprocs=6 threads=5 spinningthreads=1 idlethreads=0 runqueue=0 [1 0 0 0 0 0 0 0]
...
SCHED 0ms: gomaxprocs=8 idleprocs=6 threads=5 spinningthreads=1 idlethreads=2 runqueue=0 [0 0 0 0 0 0 0 0]
SCHED 0ms: gomaxprocs=8 idleprocs=6 threads=5 spinningthreads=1 idlethreads=2 runqueue=0 [9 0 0 0 0 0 0 0]
SCHED 1007ms: gomaxprocs=8 idleprocs=8 threads=13 spinningthreads=0 idlethreads=6 runqueue=0 [0 0 0 0 0 0 0 0]
输出结果说明
名称 | 描述 |
---|---|
SCHED | 标志字符串,代表 goroutine 调度器 |
0ms | 从程序启动到输出这行日志的时间 |
gomaxprocs | P 的数量,(默认的 P 和 CPU 核心数量一致 |
idleprocs | 空闲状态的 P 的数量 |
threads | 线程数量 |
spinningthreads | 自旋状态的线程数量 |
idlethread | 空闲状态的线程数量 |
runqueue | 全局队列中 G 的数量 |
[0 … 0] | 每个 P 的本地队列中 G 的数量 |
输出 GC 时内存示例
执行命令
$ GODEBUG=gctrace=1 go run main.go
# 输出如下
gc 1 @0.028s 1%: 0.058+1.1+0.19 ms clock, 0.46+0/1.0/0.36+1.5 ms cpu, 3->4->0 MB, 4 MB goal, 0 MB stacks, 0 MB globals, 8 P
gc 2 @0.034s 1%: 0.083+0.63+0.005 ms clock, 0.66+0.094/0.51/0.27+0.044 ms cpu, 3->3->0 MB, 4 MB goal, 0 MB stacks, 0 MB globals, 8 P
gc 3 @0.039s 1%: 0.031+0.66+0.042 ms clock, 0.25+0.091/0.49/0.39+0.34 ms cpu, 3->4->0 MB, 4 MB goal, 0 MB stacks, 0 MB globals, 8 P
gc 4 @0.043s 2%: 0.027+0.70+0.14 ms clock, 0.22+0.039/0.50/0.34+1.1 ms cpu, 3->3->0 MB, 4 MB goal, 0 MB stacks, 0 MB globals, 8 P
...
gc 1 @0.002s 4%: 0.012+0.78+0.005 ms clock, 0.098+0.49/0.58/0.32+0.040 ms cpu, 4->6->5 MB, 4 MB goal, 0 MB stacks, 0 MB globals, 8 P
gc 2 @0.015s 2%: 0.016+1.3+0.034 ms clock, 0.12+0.022/1.1/0.90+0.27 ms cpu, 9->9->7 MB, 10 MB goal, 0 MB stacks, 0 MB globals, 8 P
输出结果说明
名称 | 描述 |
---|---|
gc | GC 次数编号,每次 GC 时递增 |
@#s | 距离程序开始执行的时间 |
#% | GC 执行占用的时间百分比 |
#ms | GC 使用的时间 |
#MB | GC 开始前,结束时,当前正在被使用堆内存的大小 |
MB goal | 下一次触发 GC 的堆大小 |
MB stacks | 估计扫描栈大小 |
MB global | 可扫描的全局大小 |
#P | P 的数量 |
下面以最后一行输出为例进行说明:
gc 2 @0.015s 2%: 0.016+1.3+0.034 ms clock, 0.12+0.022/1.1/0.90+0.27 ms cpu, 9->9->7 MB, 10 MB goal, 0 MB stacks, 0 MB globals, 8 P
名称 | 描述 |
---|---|
gc 17 | GC 编号为 2 |
@0.015s | 程序已经执行了 0.015s |
2% | GC 执行占用的时间为 1% |
0.016+1.3+0.034 ms clock | GC 使用时间,分别为 STW 清扫的时间 + 并发标记和扫描的时间 + STW 标记的时间 |
0.12+0.022/1.1/0.90+0.27 ms cpu | GC 占用 CPU 时间 |
9->9->7 MB | GC 开始前堆内存 9 M, 结束时堆内存 9 M,当前正在被使用堆内存 7 M |
10 MB goal | 下一次触发 GC 的堆大小为 10M |
8 P | P 的数量为 8 个 |
输出调度完整信息
执行命令
$ GODEBUG=scheddetail=1,schedtrace=1000 go run main.go
# 输出如下
SCHED 0ms: gomaxprocs=8 idleprocs=6 threads=6 spinningthreads=1 idlethreads=2 runqueue=0 gcwaiting=0 nmidlelocked=0 stopwait=0 sysmonwait=0
P0: status=1 schedtick=1 syscalltick=0 m=0 runqsize=0 gfreecnt=0 timerslen=0
P1: status=0 schedtick=2 syscalltick=0 m=-1 runqsize=0 gfreecnt=0 timerslen=0
...
P7: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0 timerslen=0
M5: p=2 curg=-1 mallocing=0 throwing=0 preemptoff= locks=1 dying=0 spinning=true blocked=false lockedg=-1
...
M0: p=0 curg=1 mallocing=0 throwing=0 preemptoff= locks=5 dying=0 spinning=false blocked=false lockedg=1
G1: status=2(chan receive) m=0 lockedm=0
...
G4: status=4(GC scavenge wait) m=-1 lockedm=-1
...
SCHED 1008ms: gomaxprocs=8 idleprocs=8 threads=14 spinningthreads=0 idlethreads=7 runqueue=0 gcwaiting=0 nmidlelocked=1 stopwait=0 sysmonwait=0
P0: status=0 schedtick=262 syscalltick=826 m=-1 runqsize=0 gfreecnt=0 timerslen=0
...
P7: status=0 schedtick=17 syscalltick=307 m=-1 runqsize=0 gfreecnt=3 timerslen=0
M13: p=-1 curg=-1 mallocing=0 throwing=0 preemptoff= locks=0 dying=0 spinning=false blocked=true lockedg=-1
...
M0: p=-1 curg=-1 mallocing=0 throwing=0 preemptoff= locks=0 dying=0 spinning=false blocked=true lockedg=-1
G1: status=4(semacquire) m=-1 lockedm=-1
G17: status=6() m=1 lockedm=1
G2: status=4(force gc (idle)) m=-1 lockedm=-1
G3: status=4(GC sweep wait) m=-1 lockedm=-1
G4: status=4(sleep) m=-1 lockedm=-1
G5: status=4(finalizer wait) m=-1 lockedm=-1
G12: status=6() m=-1 lockedm=-1
G22: status=6() m=-1 lockedm=-1
G10: status=4(GC worker (idle)) m=-1 lockedm=-1
...
G78: status=4(select) m=-1 lockedm=10
G146: status=4(chan receive) m=-1 lockedm=-1
输出结果说明
P
的相关输出说明,以下面这行输出为例:
P0: status=1 schedtick=1 syscalltick=0 m=0 runqsize=0 gfreecnt=0 timerslen=0
名称 | 描述 |
---|---|
P0 | 编号 |
status | 状态 |
schedtick | 调度次数 |
syscalltick | 系统调用次数 |
m | 关联的 M |
runqsize | 运行队列中 G 的数量 |
gfreecnt | 可用的 G 的数量 |
timerslen | 关联的定时器数量 |
P
的状态列表
const (
// 处理器没有在执行代码或者调度,位于空闲列表或者被可以改变其状态的结构持有
_Pidle = iota
// 处理器被线程 M 持有,并且正在执行代码或者调度
_Prunning
// 处理器没有在执行代码,线程陷入系统调用
_Psyscall
// 处理器被线程 M 持有,由于 GC 被停止
_Pgcstop
// 处理器不再被使用
_Pdead
)
M
的相关输出说明,以下面这行输出为例:
M0: p=0 curg=1 mallocing=0 throwing=0 preemptoff= locks=5 dying=0 spinning=false blocked=false lockedg=1
名称 | 描述 |
---|---|
M0 | 编号 |
p | 关联的 P |
curg | 当前运行的 G |
mallocing | 是否正在分配内存 |
throwing | 是否抛出异常 |
preemptoff | 是否和当前运行的 G 绑定 |
locks | 锁 |
dying | 销毁状态 |
spinning | 是否正在自旋 |
blocked | 是否阻塞 |
G
的相关输出说明,以下面这行输出为例:
G1: status=2(chan receive) m=0 lockedm=0
名称 | 描述 |
---|---|
G1 | 编号 |
status | 状态 |
m | 关联的 M |
G
的状态列表
const (
// goroutine 刚被分配并且还没有被初始化
_Gidle = iota // 0
// goroutine 处于运行队列中,没有在执行代码,没有栈的所有权
_Grunnable // 1
// goroutine 可以执行代码并且拥有有栈的所有权,M 和 P 已经设置并且有效
_Grunning // 2
// goroutine 正在执行系统调用,没有在执行代码,拥有栈的所有权但是不在运行队列中,此外,M 已经设置
_Gsyscall // 3
// goroutine 处于阻塞中,没有在执行代码并且不在运行队列中,但是可能存在于 Channel 的等待队列上
_Gwaiting // 4
// 没有使用这个状态,但是被硬编码到了 gbd 脚本中
_Gmoribund_unused // 5
// goroutine 没有被使用 (可能已经退出或刚刚初始化),没有在执行代码,可能存在分配的栈
_Gdead // 6
// 没有使用这个状态
_Genqueue_unused // 7
// goroutine 的栈正在被移动,没有在执行代码并且不在运行队列中
_Gcopystack // 8
// goroutine 由于抢占而阻塞,等待唤醒
_Gpreempted // 9
// GC 正在扫描栈空间,没有在执行代码,可以与上述其他状态同时存在
_Gscan = 0x1000
)
*声明:本文于网络整理,如来源信息有误或侵犯权益,请联系我删除或授权事宜。
I think the admin of this site is actually working hard in favor of his web page,
since here every information is quality based stuff.
Way cool! Some extremely valid points! I appreciate you penning this post and the rest of the website is also very good.
I was excited to uncover this web site. I wanted to thank you for ones time for this particularly wonderful read!!
I definitely savored every bit of it and i also have
you book-marked to check out new stuff on your blog.
I’m really enjoying the theme/design of your web site.
Do you ever run into any web browser compatibility issues?
A handful of my blog readers have complained about my site not operating correctly in Explorer but looks
great in Safari. Do you have any recommendations to help fix this issue?
This piece of writing will help the internet visitors for creating new weblog or even a weblog from
start to end.
I enjoy reading a post that will make people think. Also, many thanks for permitting me
to comment!
Its like you read my mind! You seem to know a lot about this, like you
wrote the book in it or something. I think that you can do with some
pics to drive the message home a little bit, but other than that, this is wonderful blog.
A fantastic read. I’ll definitely be back.
Hi, just wanted to say, I enjoyed this post.
It was inspiring. Keep on posting!
Hello There. I found your blog the use of msn. That is a really neatly written article.
I will be sure to bookmark it and come back to read more of your useful information. Thank
you for the post. I will definitely return.
This is very interesting, You’re a very skilled blogger.
I’ve joined your rss feed and look forward to seeking more of your
magnificent post. Also, I’ve shared your web site in my social networks!
It’s a shame you don’t have a donate button! I’d definitely donate to this fantastic
blog! I guess for now i’ll settle for book-marking and
adding your RSS feed to my Google account. I look forward
to brand new updates and will talk about this website with my Facebook group.
Talk soon!
My web page: check here (Della)
If considering donations, I can provide my contact information and display the advertising you need on my blog
My brother recommended I might like this blog.
He was totally right. This post actually made my day.
You can not imagine simply how much time I had spent for this info!
Thanks!
I am extremely impressed with your writing skills and also with the layout
on your blog. Is this a paid theme or did you modify it yourself?
Anyway keep up the excellent quality writing, it’s rare to see
a nice blog like this one nowadays.
I modified it myself
Admiring the time and energy you put into your website and detailed information you offer.
It’s awesome to come across a blog every once in a while that isn’t
the same out of date rehashed information. Wonderful read!
I’ve saved your site and I’m including your RSS feeds
to my Google account.
Pretty section of content. I just stumbled upon your site and in accession capital to assert that I acquire in fact enjoyed account your blog posts.
Anyway I will be subscribing to your feeds and even I
achievement you access consistently fast.
I was able to find good info from your content.
Post writing is also a excitement, if you know then you can write otherwise
it is complicated to write.
Hello, I desire to subscribe for this website to take most up-to-date
updates, so where can i do it please help out.
Thank you for this insightful post!
Attractive section of content. I just stumbled upon your website
and in accession capital to assert that I get actually enjoyed
account your blog posts. Any way I’ll be subscribing to your augment and even I achievement
you access consistently rapidly.
Just desire to say your article is as astonishing. The clarity to
your put up is just great and i can assume you’re an expert in this subject.
Well with your permission let me to take hold of your feed to stay
up to date with impending post. Thanks a million and please carry on the gratifying work.
Admiring the dedication you put into your website and detailed information you provide.
It’s good to come across a blog every once in a while that isn’t
the same out of date rehashed information. Fantastic read!
I’ve saved your site and I’m adding your RSS feeds to my Google account.
It’s hard to come by experienced people for this subject,
however, you seem like you know what you’re talking about!
Thanks
Hi everyone, it’s my first visit at this website,
and article is genuinely fruitful in favor of me, keep up posting these
types of content.
There is certainly a lot to know about this topic. I like all the points
you have made.
I enjoy what you guys tend to be up too. This sort of clever work
and reporting! Keep up the superb works guys I’ve incorporated you guys to our blogroll.
We absolutely love your blog and find a lot of your post’s to be what precisely I’m looking for.
Does one offer guest writers to write content to suit your needs?
I wouldn’t mind creating a post or elaborating on a few of the subjects you write with regards to
here. Again, awesome website!
Excellent post however I was wondering if you could
write a litte more on this subject? I’d be very thankful if you could elaborate a little
bit further. Thanks!
After exploring a number of the blog posts on your site, I truly like your technique of writing a blog.
I book marked it to my bookmark webpage list and will be checking back soon.
Take a look at my website as well and tell me what you think.
Hello there, just became aware of your blog through Google, and found that
it’s truly informative. I am gonna watch out for brussels.
I will be grateful if you continue this in future. A lot of people will be benefited from your writing.
Cheers!
Hello all, here every person is sharing these know-how, so it’s nice
to read this web site, and I used to pay a visit this weblog daily.
Hi mates, how is the whole thing, and what you wish for to
say about this article, in my view its actually amazing in support of me.
I am really pleased to read this webpage posts which consists of lots of helpful information, thanks for providing these kinds
of information.
For latest information you have to visit world-wide-web and on internet I found this site as
a finest web site for latest updates.
Good article. I’m experiencing a few of these issues as well..
You ought to be a part of a contest for one of the finest sites
on the internet. I am going to highly recommend this site!
I was able to find good advice from your content.
This is very interesting, You are a very professional blogger.
I’ve joined your rss feed and look forward to
seeking extra of your magnificent post. Also, I’ve shared
your web site in my social networks
Sweet blog! I found it while surfing around on Yahoo News.
Do you have any suggestions on how to get listed in Yahoo News?
I’ve been trying for a while but I never seem to get there!
Thanks
Hi friends, how is the whole thing, and what you wish for to say about this paragraph, in my view its in fact awesome designed for
me.
Thanks to my father who told me regarding this webpage, this web site is in fact remarkable.
Hey there! I simply wish to offer you a big thumbs
up for the great info you have right here on this post.
I am coming back to your web site for more soon.
Hello, i believe that i noticed you visited my weblog so i got
here to go back the favor?.I am trying to in finding issues to improve my site!I assume its good enough to make use of some of
your ideas!!
I am actually glad to glance at this weblog posts which includes lots of valuable facts, thanks for
providing these kinds of data.
Hi there, I enjoy reading through your post.
I like to write a little comment to support you.
I am really loving the theme/design of your
site. Do you ever run into any internet browser compatibility
problems? A couple of my blog audience have complained about my blog not operating
correctly in Explorer but looks great in Chrome.
Do you have any tips to help fix this issue?
Wonderful goods from you, man. I’ve be mindful your stuff previous to and you are simply extremely wonderful.
I actually like what you have bought here, certainly like what you are saying and the way in which through which
you assert it. You are making it enjoyable and you still
take care of to keep it sensible. I can’t wait to learn much more from you.
This is really a terrific site.
Heya just wanted to give you a brief heads
up and let you know a few of the images aren’t loading properly.
I’m not sure why but I think its a linking issue.
I’ve tried it in two different browsers and both show the same outcome.
Thank you for the auspicious writeup. It in truth used
to be a amusement account it. Look complicated to more delivered agreeable from you!
By the way, how could we keep in touch?
WeChat ID:dmwz1995
Thanks , I’ve recently been searching for info approximately this topic for a while and yours is
the best I’ve discovered so far. However, what about the bottom line?
Are you certain about the source?
Good post. I learn something new and challenging on blogs I stumbleupon every day.
It’s always useful to read articles from other authors and practice a little something from other websites.
Hi there everyone, it’s my first visit at this site, and paragraph is in fact
fruitful for me, keep up posting these types of content.
Hello, Neat post. There is a problem with your web site in internet explorer, could check this?
IE still is the market chief and a huge part of other people will omit your wonderful writing due to this problem.
Okay, I will check. Thank you for your feedback
Have you ever thought about creating an ebook or guest authoring on other sites?
I have a blog based upon on the same subjects you discuss and would
love to have you share some stories/information. I
know my viewers would appreciate your work. If you’re even remotely interested, feel free to send me an e mail.
This blog was… how do you say it? Relevant!! Finally I have found
something which helped me. Thanks!
Very quickly this web page will be famous amid all blog visitors, due to
it’s pleasant content
Hey very nice blog!
I every time spent my half an hour to read this webpage’s
articles all the time along with a mug of coffee.
Spot on with this write-up, I seriously believe this amazing site needs a lot more attention. I’ll probably be returning to see more, thanks for the information!
What’s up friends, pleasant article and fastidious arguments commented here, I
am actually enjoying by these.