go 运行时:始终记录内存中的GC详细信息

jhdbpxl9  于 2个月前  发布在  Go
关注(0)|答案(9)|浏览(28)

当用户报告与垃圾回收器(GC)相关的潜在问题时,我们首先要求的是GC跟踪(GODEBUG=gctrace=1)。但我们很少得到它。
将gctrace设置为1是足够便宜的,可以一直保持开启,但向stderr发送垃圾信息是不礼貌的。相反,运行时可以在内存中的某个地方记录它,无论是文本还是结构化数据,并在/debug处理程序或其他地方公开它。这样就更容易按需提取了。
这对于GODEBUG=sched{detail,trace}也可能是有用的,但我还没有看到这种情况经常出现。

bt1cpqcv

bt1cpqcv2#

有人在做这个吗?如果没有,我可以尝试一下。
原型:78ec37e
它将runtime.MemStats(几乎包含了gctrace=1打印的所有内容)放入内部循环缓冲区,并通过runtime.ReadAllMemStats()暴露出来。它还没有在/debug处理器上暴露任何内容。
是否应该从GODEBUG中获取缓冲区大小?

plicqrtu

plicqrtu3#

目前我所知的,没有人在做这件事,所以请随意。但如果我们只想要MemStats,我们可以直接调用ReadMemStats。通常我们想要知道每个阶段的CPU/墙钟时间,而这并不在里面,只有STW暂停墙钟时间。
也许最简单的方法是将额外的信息添加到MemStats中。但这将被Go兼容性承诺覆盖...

kcrjzv8t

kcrjzv8t4#

也许实现这个目标最简单的方法是将额外的信息添加到MemStats中。但这将受到Go兼容性承诺的限制
我假设这里有一个拼写错误。因为评论说“由于向后兼容性,我们不能改变MemStats”。或者我漏掉了什么?

rbpvctlc

rbpvctlc5#

我假设(没有验证)这是指内部含义发生变化的字段,我们不能将这种变化传播到公共结构中,因为它可能会破坏现有的代码。添加字段应该是可以的。

rggaifut

rggaifut6#

有一个明确的检查,用于在添加新字段时失败。它于2010年添加:dc9a3b2#diff-17dbb5a92bd43f80a1909a1814e2d42eR82。
据我所知,当时部分代码是用C编写的,部分用Go编写;这个检查是为了确保两个大小匹配。但现在情况已经不同了。那么,我们可以安全地移除这个检查吗?

y4ekin9u

y4ekin9u7#

感谢您承担这项工作。无需通过添加GODEBUG标志来过度工程化代码。添加标志是一个非常重的更改。为了上下文,垃圾回收器目前只有1个标志,经过10个发布。代码应该选择一个合理的大小,并将其作为实现特定值进行记录。如果大小太小,我们可以在了解用例后向上调整...。
2018年2月28日星期三晚上7:11,Dhananjay Nakrani @***. >写道:有人在做这个吗?如果没有,我可以试试看。原型:78ec37e < JayNakrani@78ec37e>。它将运行时.MemStats输出到内部循环缓冲区,并通过runtime.ReadAllMemStats()公开。它尚未在/debug处理程序上公开任何内容。是否应该从GODEBUG中获取缓冲区大小?—您收到此邮件是因为您订阅了此线程。直接回复此电子邮件,查看GitHub上的<#23815 (comment)>或静音线程< https://github.com/notifications/unsubscribe-auth/AA7Wn4TDetKNLbohW8LCGI-NMP6xPMaaks5tZzyrgaJpZM4SEU3A > 。

kkih6yb8

kkih6yb88#

关于在合理的缓冲区预算下,有人调试垃圾回收(GC)问题时希望看到的内容的一些想法:

  1. 前10个周期。
  2. 最后10个GC周期。
  3. 最后100个周期中的每十个GC周期。
  4. 最后1000个周期中的每100个GC周期。
  5. 最后10,000个周期中的每1000个GC周期。
    这是一个固定的50个周期的缓冲区,覆盖了最后10K个GC周期。

——Rick Hudson

yrefmtwq

yrefmtwq9#

https://golang.org/cl/98335提到了这个问题:runtime: Expose MemStats for previous GC cycles.

相关问题