GOGCTRACE和垃圾回收时间

6

Go支持GOGCTRACE环境变量,并在每次运行时打印收集统计信息。但它不会打印GC发生的时间。例如:

gc6231(8): 0+1+0 毫秒,10 -> 5 MB 89540 -> 5294 (520316701-520311407) 对象,9(80) 移交,32(404) 偷窃,288/168/37 产量

我该如何将收集行与其发生的时间相关联?


看起来 GOGCTRACE 已不再受支持:http://grokbase.com/t/gg/golang-dev/137p2tm5f1/has-gogctrace-been-removed-or-renamed - Sandeep Raju Prabhakar
1个回答

7
跟踪记录显示的不是绝对时间,而是相对于输出的时间。 当该行出现时,GC发生在0 + 1 + 0毫秒前。 请参考代码中相应的输出行
如果你在标准输出上每行加上时间戳,你就可以得到GC运行的时间(时间戳-毫秒数=GC运行时间)。
例如:
GOGCTRACE=1 ./myprog 2>&1 | while read line; do echo $(date +%s) $line; done

如果你只是想感受垃圾回收运行时的准确时间,那么这完全足够了。输出很可能不会滞后太多,即使有滞后,你仍然可以使用时间戳获取正确的时间。
另一个解决方案是使用runtime/debug中的ReadGCStats函数,它会给你GCStats结构体,该结构体又有一个LastGC字段,类型为time.Time,保存着最后一次垃圾回收运行的绝对时间。或者你可以使用runtime.ReadMemStats函数,它会给你更多信息。
当然,您仍需要知道垃圾回收发生的时间。为此,您可以在一个仅用于垃圾回收的对象上使用finalizer,并在其上应用runtime.SetFinalizer。在finalizer中,您将读取LastGC时间并将其打印出来。
示例(在play上):
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
    }
}

我需要垃圾回收发生的绝对时间。 - Matt Joiner
那么,如果你有相对时间,并在每行前缀绝对时间,那么你就可以看到GC运行的绝对时间。例如:./myprog | while read line; do echo $(date +%s) $line; done - nemo
这个回答非常详尽,太棒了。 - Matt Joiner
你喜欢它很高兴,不过它有帮助吗? - nemo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接