go逃逸分析

Go 逃逸分析

堆和棧

堆(Heap):

一般來講是人為手動進行管理,手動申請、分配、釋放。堆適合不可預(yù)知大小的內(nèi)存分配,這也意味著為此付出的代價是分配速度較慢,而且會形成內(nèi)存碎片。

棧(Stack):

由編譯器進行管理,自動申請、分配、釋放。一般不會太大,因此棧的分配和回收速度非???;我們常見的函數(shù)參數(shù)(不同平臺允許存放的數(shù)量不同),局部變量等都會存放在棧上。
棧分配內(nèi)存只需要兩個CPU指令:“PUSH”和“RELEASE”,分配和釋放;而堆分配內(nèi)存首先需要去找到一塊大小合適的內(nèi)存塊,之后要通過垃圾回收才能釋放。

通俗比喻的說,棧就如我們?nèi)ワ堭^吃飯,只需要點菜(發(fā)出申請)--》吃吃吃(使用內(nèi)存)--》吃飽就跑剩下的交給飯館(操作系統(tǒng)自動回收),而堆就如在家里做飯,大到家,小到買什么菜,每一個環(huán)節(jié)都需要自己來實現(xiàn),但是自由度會大很多。

什么是逃逸分析

在編譯程序優(yōu)化理論中,逃逸分析是一種確定指針動態(tài)范圍的方法,簡單來說就是分析在程序的哪些地方可以訪問到該指針。

再往簡單的說,Go是通過在編譯器里做逃逸分析(escape analysis)來決定一個對象放棧上還是放堆上,不逃逸的對象放棧上,可能逃逸的放堆上;即我發(fā)現(xiàn)變量在退出函數(shù)后沒有用了,那么就把丟到棧上,畢竟棧上的內(nèi)存分配和回收比堆上快很多;反之,函數(shù)內(nèi)的普通變量經(jīng)過逃逸分析后,發(fā)現(xiàn)在函數(shù)退出后變量還有在其他地方上引用,那就將變量分配在堆上。做到按需分。

為何需要逃逸分析

ok,了解完堆和棧各自的優(yōu)缺點后,我們就可以更好的知道逃逸分析存在的目的了:

減少gc壓力,棧上的變量,隨著函數(shù)退出后系統(tǒng)直接回收,不需要gc標(biāo)記后再清除。

減少內(nèi)存碎片的產(chǎn)生。

減輕分配堆內(nèi)存的開銷,提高程序的運行速度。

如何確定是否逃逸

在Go中通過逃逸分析日志來確定變量是否逃逸,開啟逃逸分析日志:

go run -gcflags '-m -m -m -m -l' main.go
-m 會打印出逃逸分析的優(yōu)化策略,實際上最多總共可以用 4 個 -m,但是信息量較大,一般用 1 個就可以了。

-l 會禁用函數(shù)內(nèi)聯(lián),在這里禁用掉內(nèi)聯(lián)能更好的觀察逃逸情況,減少干擾。

什么情況下會發(fā)生逃逸分析

堆棧占用內(nèi)存
1 指針引用,常見函數(shù)間指針參數(shù)以及返回值
2 interface不明類型的調(diào)用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容