Golang 記憶體逃逸分析

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

0x01 什麼是逃逸

第一次聽說逃逸是在雨痕學堂,一臉懵逼的百度了半天也沒找到一個明確的說法,直到昨天在論壇上看到一篇關於變數逃逸的文章才明白。

因為函數都是運行在棧上的,在棧聲明臨時變數分配記憶體,函數運行完畢再回收該段棧空間,並且每個函數的棧空間都是獨立的,其他代碼都是不可訪問的。

但是在某些情況下,棧上的空間需要在該函數被釋放後依舊能訪問到,這時候就涉及到記憶體的逃逸了。

代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type data struct {
name string
}
//go:noinline
func f1()data{
d := data{"maqian"}
return d
}
//go:noinline
func f2() *data {
d := data{"maqian"}
return &d
}
func main(){
d1 := f1()
d2 := f2()
}

f1和f2兩個函數都是建立一個變數返回,不同的是f1返回變數副本,f2返回變數指標。在大多數語言例如C/C++,類似f2的函數是不對的,因為d是一個臨時變數,return過後就會被釋放掉,返回毫無意義。但是在golang中,這種文法是允許的,它能正確的把d的地址返回到上層調用函數而不被釋放。

正如上面所說,該函數在運行完畢後肯定是要釋放的,內部分配的臨時記憶體也要釋放,所以d也應該被釋放。而為了讓d能被正確返回到上層調用,golang採取了一種記憶體策略,把d從棧拿到堆的中去,此時d就不會跟隨f2一同消亡了,這個過程就是一次逃逸。

0x02 編譯報告

代碼中兩個函數上方的go:noinline 注釋是一個編譯標記,讓編譯器不內聯當前代碼方便觀察編譯狀態。因為這裡代碼十分簡單,不給標記編譯器會自動內聯該段代碼看不到效果。

在編譯時間可以通過gcflags 選項帶上-m 參數查看到編譯狀態,-m 一共可以攜帶四個:

1
2
3
4
5
6
7
8
9
10
[ma@ma escape_analysis]$ go build -o app -gcflags "-m -m"
# _/data/code/go/src/test-src/level6-other/escape_analysis
./escape.go:8:6: cannot inline f1: marked go:noinline
./escape.go:14:6: cannot inline f2: marked go:noinline
./escape.go:19:6: cannot inline main: non-leaf function
./escape.go:16:9: &d escapes to heap
./escape.go:16:9: from ~r0 (return) at ./escape.go:16:2
./escape.go:15:20: moved to heap: d
./escape.go:20:8: d1 declared and not used
./escape.go:21:8: d2 declared and not used

通過第四行和第五行輸出很直接就能看出,在代碼的第16行,即函數f2return 處,參數d產生了逃逸行為。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.