Go 支持GOGCTRACE环境变量,并在每次运行时打印收集统计信息。但是,当 GC 发生时它不会打印。例子:
gc6231(8): 0+1+0 ms, 10 -> 5 MB 89540 -> 5294 (520316701-520311407) 个对象, 9(80) 切换, 32(404) 偷窃, 288/168/37 产量
我如何将收集线与它发生的时间关联起来?
Go 支持GOGCTRACE环境变量,并在每次运行时打印收集统计信息。但是,当 GC 发生时它不会打印。例子:
gc6231(8): 0+1+0 ms, 10 -> 5 MB 89540 -> 5294 (520316701-520311407) 个对象, 9(80) 切换, 32(404) 偷窃, 288/168/37 产量
我如何将收集线与它发生的时间关联起来?
迹线不显示绝对时间,而是显示相对于输出的时间。当线路发生时,GC 发生在0 + 1 + 0
ms 前。
请参阅代码中相应的输出行以供参考。
如果您在标准输出上的每一行前加上时间戳,那么您将获得 GC 运行的时间(时间戳 - 以毫秒为单位的时间 = GC 运行的时间)。
例子:
GOGCTRACE=1 ./myprog 2>&1 | while read line; do echo $(date +%s) $line; done
如果您只是想在 GC 运行以几秒的精度发生时有一种感觉,那么这完全足够了。输出很可能不会落后太多,即使确实如此,您仍然有时间戳来获得正确的时间。
另一种解决方案是使用ReadGCStats
from runtime/debug
which 为您提供GCStats
结构,该结构又具有LastGC
type字段time.Time
,保存上次 GC 运行的绝对时间。或者,您可以使用runtime.ReadMemStats
,它会为您提供更多信息。
当然,您仍然需要知道垃圾收集何时发生。为此,您可以在您创建的对象上使用终结器,该对象仅用于进行垃圾收集并应用于runtime.SetFinalizer
该对象。在终结器中,您将读取LastGC
时间并打印它。
示例(正在播放):
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
}
}