10.8 垃圾回收和 SetFinalizer
Go 開發者不需要寫代碼來釋放程序中不再使用的變量和結構佔用的內存,在 Go 運行時中有一個獨立的進程,即垃圾收集器(GC),會處理這些事情,它搜索不再使用的變量然後釋放它們的內存。可以通過 runtime
包訪問 GC 進程。
通過調用 runtime.GC()
函數可以顯式的觸發 GC,但這隻在某些罕見的場景下才有用,比如當內存資源不足時調用 runtime.GC()
,它會此函數執行的點上立即釋放一大片內存,此時程序可能會有短時的性能下降(因爲 GC
進程在執行)。
如果想知道當前的內存狀態,可以使用:
// fmt.Printf("%d\n", runtime.MemStats.Alloc/1024)
// 此處代碼在 Go 1.5.1下不再有效,更正爲
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%d Kb\n", m.Alloc / 1024)
上面的程序會給出已分配內存的總量,單位是 Kb。進一步的測量參考 文檔頁面。
如果需要在一個對象 obj 被從內存移除前執行一些特殊操作,比如寫到日誌文件中,可以通過如下方式調用函數來實現:
runtime.SetFinalizer(obj, func(obj *typeObj))
func(obj *typeObj)
需要一個 typeObj
類型的指針參數 obj
,特殊操作會在它上面執行。func
也可以是一個匿名函數。
在對象被 GC 進程選中並從內存中移除以前,SetFinalizer
都不會執行,即使程序正常結束或者發生錯誤。
練習 10.17
從練習 10.16 開始(它基於結構體實現了一個棧結構),爲棧的實現(stack_struct.go)創建一個單獨的包 stack
,並從 main
包 main.stack.go
中調用它。