Go語言逃逸分析

本貼轉(zhuǎn)自https://www.cnblogs.com/itbsl/p/10476674.html
如侵權(quán)击碗,請(qǐng)聯(lián)系QQ359152155刪除。

Go變量逃逸分析

逃逸分析 決定一個(gè)變量是分配在堆上還是棧上啡浊。

逃逸分析這種操作把變量合理地分配到它該去的地方醋拧,即使你是用new申請(qǐng)到的內(nèi)存畜晰,如果我發(fā)現(xiàn)你竟然在退出函數(shù)后就沒有用了西土,那么就把你丟到棧上陆错,畢竟棧上的內(nèi)存分配比堆上快得多魄揉;反之剪侮,即使你表面上只是一個(gè)普通的變量,但是經(jīng)過逃逸分析后發(fā)現(xiàn)在退出函數(shù)之后還有其他地方在引用洛退,那我就把你分配到堆上瓣俯。

如果變量都分配到堆上,堆不像棻樱可以自動(dòng)清理彩匕,它會(huì)引起Go頻繁地進(jìn)行垃圾回收,而垃圾回收會(huì)占用比較大的系統(tǒng)開銷媒区。

通過逃逸分析驼仪,可以盡量把哪些不需要分配到對(duì)上的變量直接分配到棧上,堆上的變量少了袜漩,會(huì)減輕分配堆內(nèi)存的開銷绪爸,同時(shí)也會(huì)減少GC的壓力,提高程序的運(yùn)行速度宙攻。

逃逸分析是怎么完成的

Go逃逸分析的最基本原則是:如果一個(gè)函數(shù)返回堆一個(gè)變量的引用奠货,那么它就會(huì)發(fā)生逃逸。

編譯器會(huì)分析代碼的特征和代碼生命周期座掘,Go中的變量只有在編譯器可以證明在函數(shù)返回后不會(huì)再被引用递惋,才會(huì)分配到棧上,其他情況下都是分配到堆上雹顺。

逃逸分析實(shí)例

Go提供了相關(guān)的命令丹墨,可以查看變量是否發(fā)生逃逸。

用下面這個(gè)例子:

package main

import "fmt"

func foo() *int {
    t := 3
    return &t;
}

func main() {
    x := foo()
    fmt.Println(*x)
}

foo函數(shù)返回一個(gè)局部變量的指針嬉愧,main函數(shù)里變量x接收它贩挣。執(zhí)行如下命令:

go build -gcflags="-m -l" main.go

-l是為了不讓foo函數(shù)被內(nèi)聯(lián),得到如下輸出:

# command-line-arguments
.\hello.go:6:5: moved to heap: t
.\hello.go:12:16: ... argument does not escape
.\hello.go:12:17: *x escapes to heap

foo函數(shù)里的變量t逃逸了没酣,和我們預(yù)想的一致王财。讓我們不解的是為什么main函數(shù)里的*x也逃逸了?這是因?yàn)閒mt.Println()函數(shù)的參數(shù)是interface類型裕便,編譯期間很難確定其參數(shù)的具體類型绒净,也會(huì)發(fā)生逃逸。

總結(jié)

堆上動(dòng)態(tài)分配內(nèi)存比棧上靜態(tài)分配內(nèi)存偿衰,開銷大很多挂疆。

Go編譯器會(huì)在編譯器分析變量的生命周期改览,編譯器會(huì)根據(jù)變量是否在函數(shù)返回后仍舊被引用來決定是否逃逸。對(duì)于Go程序原來說缤言,編譯器的這些逃逸分析規(guī)則不需要掌握宝当,我們只需通過`go build -gcflags="-m"命令來觀察變量逃逸情況就行了。

不要盲目使用變量的指針作為函數(shù)參數(shù)胆萧,雖然它會(huì)減少復(fù)制操作庆揩,但其實(shí)當(dāng)參數(shù)為變量自身的時(shí)候,復(fù)制是在站上完成的操作跌穗,開銷遠(yuǎn)比變量逃逸后動(dòng)態(tài)地在堆上分配內(nèi)存少的多订晌。

最后,盡量寫出少一些逃逸的代碼蚌吸,提升程序的運(yùn)行效率锈拨。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市套利,隨后出現(xiàn)的幾起案子推励,更是在濱河造成了極大的恐慌鹤耍,老刑警劉巖肉迫,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異稿黄,居然都是意外死亡喊衫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門杆怕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來族购,“玉大人,你說我怎么就攤上這事陵珍∏拚龋” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵互纯,是天一觀的道長瑟幕。 經(jīng)常有香客問我,道長留潦,這世上最難降的妖魔是什么只盹? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮兔院,結(jié)果婚禮上殖卑,老公的妹妹穿的比我還像新娘。我一直安慰自己坊萝,他們只是感情好孵稽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布许起。 她就那樣靜靜地躺著,像睡著了一般菩鲜。 火紅的嫁衣襯著肌膚如雪街氢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天睦袖,我揣著相機(jī)與錄音珊肃,去河邊找鬼。 笑死馅笙,一個(gè)胖子當(dāng)著我的面吹牛伦乔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播董习,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼烈和,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了皿淋?” 一聲冷哼從身側(cè)響起招刹,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎窝趣,沒想到半個(gè)月后疯暑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哑舒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年妇拯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洗鸵。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡越锈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出膘滨,到底是詐尸還是另有隱情甘凭,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布火邓,位于F島的核電站丹弱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贡翘。R本人自食惡果不足惜蹈矮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸣驱。 院中可真熱鬧泛鸟,春花似錦、人聲如沸踊东。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至再芋,卻和暖如春菊霜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背济赎。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國打工鉴逞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人司训。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓构捡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壳猜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子勾徽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容