Go支持GOGCTRACE环境变量,并在每次运行时打印集合统计信息。但是,GC发生时不会打印。例如:
gc6231(8):0 + 1 + 0ms,10 - > 5 MB 89540 - > 5294(520316701-520311407)对象,9(80)切换,32(404)窃取,288/168/37产量
如何将收集行与其发生的时间相关联?
答案 0 :(得分:7)
跟踪不显示绝对时间,而是显示相对于输出的绝对时间。
当该行发生时,GC发生在0 + 1 + 0
毫秒之前。
请参阅代码中的the corresponding output line以供参考。
如果在stdout上为每一行添加时间戳前缀,则可以获得GC运行的时间 (timestamp - 以毫秒为单位的时间= GC运行的时间)。
示例:
GOGCTRACE=1 ./myprog 2>&1 | while read line; do echo $(date +%s) $line; done
如果您只是想在GC运行时以秒的准确度感觉到 那就完全足够了。输出很可能不会落后很多 即使这样,你仍然有时间戳来获得正确的时间。
另一种解决方案是使用来自runtime/debug
的{{3}}
ReadGCStats
结构,后者又有一个
类型为LastGC
的字段time.Time
,保留上次GC运行的绝对时间。
或者,您可以使用GCStats
,它可以为您提供更多信息。
当然,你仍然需要知道垃圾收集何时发生。为此你可以
在您创建的对象上使用终结器,仅用于垃圾
收集并应用runtime.ReadMemStats
。
在终结器中,您将阅读LastGC
时间并打印出来。
示例(在runtime.SetFinalizer
上):
type Garbage struct{ a int }
func notify(f *Garbage) {
stats := &runtime.MemStats{}
runtime.ReadMemStats(stats)
fmt.Println("Last GC was:", stats.LastGC)
go ProduceFinalizedGarbage()
}
func ProduceFinalizedGarbage() {
x := &Garbage{}
runtime.SetFinalizer(x, notify)
}
func main() {
go ProduceFinalizedGarbage()
for {
runtime.GC()
time.Sleep(30 * time.Second) // Give GC time to run
}
}