高頻golang面試題:簡單聊聊內(nèi)存逃逸泣港?

問題

知道golang的內(nèi)存逃逸嗎暂殖?什么情況下會發(fā)生內(nèi)存逃逸?

怎么答

golang程序變量會攜帶有一組校驗數(shù)據(jù)当纱,用來證明它的整個生命周期是否在運行時完全可知呛每。如果變量通過了這些校驗,它就可以在棧上分配坡氯。否則就說它 逃逸 了晨横,必須在堆上分配

能引起變量逃逸到堆上的典型情況

  • 在方法內(nèi)把局部變量指針返回 局部變量原本應(yīng)該在棧中分配箫柳,在棧中回收手形。但是由于返回時被外部引用,因此其生命周期大于棧滞时,則溢出叁幢。
  • 發(fā)送指針或帶有指針的值到 channel 中。 在編譯時坪稽,是沒有辦法知道哪個 goroutine 會在 channel 上接收數(shù)據(jù)曼玩。所以編譯器沒法知道變量什么時候才會被釋放。
  • 在一個切片上存儲指針或帶指針的值窒百。 一個典型的例子就是 []*string 黍判。這會導(dǎo)致切片的內(nèi)容逃逸。盡管其后面的數(shù)組可能是在棧上分配的篙梢,但其引用的值一定是在堆上顷帖。
  • slice 的背后數(shù)組被重新分配了,因為 append 時可能會超出其容量( cap )渤滞。 slice 初始化的地方在編譯時是可以知道的贬墩,它最開始會在棧上分配。如果切片背后的存儲要基于運行時的數(shù)據(jù)進行擴充妄呕,就會在堆上分配陶舞。
  • 在 interface 類型上調(diào)用方法。 在 interface 類型上調(diào)用方法都是動態(tài)調(diào)度的 —— 方法的真正實現(xiàn)只能在運行時知道绪励。想像一個 io.Reader 類型的變量 r , 調(diào)用 r.Read(b) 會使得 r 的值和切片b 的背后存儲都逃逸掉肿孵,所以會在堆上分配。

舉例

  • 通過一個例子加深理解疏魏,接下來嘗試下怎么通過 go build -gcflags=-m 查看逃逸的情況停做。
package main
import "fmt"
type A struct {
 s string
}
// 這是上面提到的 "在方法內(nèi)把局部變量指針返回" 的情況
func foo(s string) *A {
 a := new(A) 
 a.s = s
 return a //返回局部變量a,在C語言中妥妥野指針,但在go則ok大莫,但a會逃逸到堆
}
func main() {
 a := foo("hello")
 b := a.s + " world"
 c := b + "!"
 fmt.Println(c)
}

執(zhí)行go build -gcflags=-m main.go

go build -gcflags=-m main.go
# command-line-arguments
./main.go:7:6: can inline foo
./main.go:13:10: inlining call to foo
./main.go:16:13: inlining call to fmt.Println
/var/folders/45/qx9lfw2s2zzgvhzg3mtzkwzc0000gn/T/go-build409982591/b001/_gomod_.go:6:6: can inline init.0
./main.go:7:10: leaking param: s
./main.go:8:10: new(A) escapes to heap
./main.go:16:13: io.Writer(os.Stdout) escapes to heap
./main.go:16:13: c escapes to heap
./main.go:15:9: b + "!" escapes to heap
./main.go:13:10: main new(A) does not escape
./main.go:14:11: main a.s + " world" does not escape
./main.go:16:13: main []interface {} literal does not escape
<autogenerated>:1: os.(*File).close .this does not escape

  • ./main.go:8:10: new(A) escapes to heap 說明 new(A) 逃逸了,符合上述提到的常見情況中的第一種蛉腌。

  • ./main.go:14:11: main a.s + " world" does not escape 說明 b 變量沒有逃逸,因為它只在方法內(nèi)存在,會在方法結(jié)束時被回收眉抬。

  • ./main.go:15:9: b + "!" escapes to heap 說明 c 變量逃逸贯吓,通過fmt.Println(a ...interface{})打印的變量,都會發(fā)生逃逸蜀变,感興趣的朋友可以去查查為什么悄谐。

  • 以上操作其實就叫逃逸分析下篇文章库北,跟大家聊聊怎么用一個比較trick的方法使變量不逃逸爬舰。方便大家在面試官面前秀一波

如果你想每天學(xué)習(xí)一個知識點寒瓦?
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末情屹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子杂腰,更是在濱河造成了極大的恐慌垃你,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喂很,死亡現(xiàn)場離奇詭異惜颇,居然都是意外死亡,警方通過查閱死者的電腦和手機少辣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門凌摄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人漓帅,你說我怎么就攤上這事锨亏。” “怎么了忙干?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵器予,是天一觀的道長。 經(jīng)常有香客問我捐迫,道長乾翔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任弓乙,我火速辦了婚禮末融,結(jié)果婚禮上钧惧,老公的妹妹穿的比我還像新娘暇韧。我一直安慰自己,他們只是感情好浓瞪,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布懈玻。 她就那樣靜靜地躺著,像睡著了一般乾颁。 火紅的嫁衣襯著肌膚如雪涂乌。 梳的紋絲不亂的頭發(fā)上艺栈,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音湾盒,去河邊找鬼湿右。 笑死,一個胖子當(dāng)著我的面吹牛罚勾,可吹牛的內(nèi)容都是我干的毅人。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尖殃,長吁一口氣:“原來是場噩夢啊……” “哼丈莺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起送丰,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤缔俄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后器躏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俐载,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年邀桑,在試婚紗的時候發(fā)現(xiàn)自己被綠了瞎疼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡壁畸,死狀恐怖贼急,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捏萍,我是刑警寧澤太抓,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站令杈,受9級特大地震影響走敌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逗噩,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一掉丽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧异雁,春花似錦捶障、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春锭部,著一層夾襖步出監(jiān)牢的瞬間暂论,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工拌禾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留取胎,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓湃窍,卻偏偏與公主長得像扼菠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子坝咐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354