GOGCTRACE和收集时间

时间:2013-06-26 03:10:21

标签: logging garbage-collection go

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

  

gc6231(8):0 + 1 + 0ms,10 - > 5 MB 89540 - > 5294(520316701-520311407)对象,9(80)切换,32(404)窃取,288/168/37产量

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

1 个答案:

答案 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
    }
}