2013-06-26 56 views
6

Go支持GOGCTRACE環境變量,並在每次運行時打印收集統計信息。但是,當GC發生時它不打印。例如:GOGCTRACE和收集時間

gc6231(8):0 + 1 + 0毫秒,10 - > 5 MB 89540 - > 5294(520316701-520311407)對象,9(80)越區切換,32(404)竊取,288/168/37收益率

如何關聯收集行與發生時間?

+0

貌似GOGCTRACE沒有更多的支持:http://grokbase.com/t/gg/golang-dev/137p2tm5f1/has-gogctrace-been-removed-或更名爲 –

回答

7

跡線不顯示絕對時間,但相對於輸出顯示一個絕對時間。 當行發生時,GC發生了0 + 1 + 0毫秒前。

參見代碼中的the corresponding output line以供參考。

如果你在標準輸出的每一行加上時間戳,你就可以得到GC運行的時間 (時間戳 - 以毫秒爲單位的時間= GC運行的時間)。

例子:

GOGCTRACE=1 ./myprog 2>&1 | while read line; do echo $(date +%s) $line; done 

如果你只是想有當GC運行發生與秒 精度的感覺,那麼這是完全足夠了。輸出很可能不會落後很多,即使是這樣,你仍然有時間戳來獲得正確的時間。

另一種解決方案是使用ReadGCStatsruntime/debug,讓你 的GCStats結構,這反過來又time.Time類型的 場LastGC,抱着最後GC運行的絕對時間。 或者,您可以使用runtime.ReadMemStats,它可以提供更多信息。

當然,你仍然需要知道垃圾收集何時發生。爲此,你可以使用一個終結器在你創建的對象上,目的是爲了收集垃圾 並在其上應用runtime.SetFinalizer。 在終結器中,您將讀取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 
    } 
} 
+0

我需要GC發生的絕對時間。 –

+0

那麼?如果你有相對的時間,並且你在絕對時間的前面加上了每行的前綴,那麼你可以看到GC運行的絕對時間。例如:'./myprog |而讀線;做echo $(date +%s)$ line; done'。 – nemo

+0

這個答案是徹底告知,布拉沃。 –