這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
golang 1.2.1的GC因為演算法的問題,在實際應用過程中,對於長時間啟動並執行daemon程式,確實很容易導致記憶體泄露,有人用cgo來手動管理記憶體,也有人用pool來管理buffer,這些都很麻煩,還是等1.3發布吧,在 golang 1.2.1中,如果注意一些坑,還是很容易寫出穩定啟動並執行程式。
1. 避免遞迴;
2.在for裡面,把一些每次重複的操作提到外面,比如包的init方法中執行, 這些不必多說,比如初始化一個資料庫連接,regexp.Compile等;
3. 函數返回,對於slice本身是引用傳遞,struct等比較大的對象,用指標,在for迴圈裡面用完將指標賦值為nil,這一點非常重要;
The garbage collector will collect memory your program no longer has a pointer to.To avoid leaking memory you just need to avoid holding on to pointers to memory you're no longer interested in using.
4.注意一些錯誤的寫法,比如:
func parseFile(file string) string {
f, err := os.Open(file)
defer f.Close()
if err != nil {
fmt.Println(err)
//os.Exit(1)
}
正確的寫法是:
func parseFile(file string) string {
f, err := os.Open(file)
if err != nil {
fmt.Println(err)
return ""
//os.Exit(1)
}else{
defer f.Close()
}
這個問題很多初學者容易犯,非常容易導致cpu消耗大,甚至報錯;
5. 減少對象的建立,盡量使用數組,struct可用做鏈表;
6. runtime.GC()沒有什麼用,go每2分鐘執行一次記憶體回收;
> What is it used for? It should use in what situation?
For example, before running a benchmark. But the runtime is free to
ignore the call or postpone performing the real GC to any later time
so it's a hint at best.
> It is useful to avoid memory leaks?
No. But it can in theory exchange longer GC pauses for more of shorter
ones and also lower the total used memory - for some programs and it
may be a win for them.
See also: http://golang.org/pkg/runtime/debug/#FreeOSMemory
7. 程式寫完跑一段時間,用go內建的效能分析工具pprof分析heap,cpu等,儘快發現問題;
8. 運行發現cpu消耗高,記憶體持續上漲怎麼辦, 寫個程式定時killall,或者crontab執行,再慢慢調優;