




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第淺談Golang內(nèi)存逃逸目錄1.什么是內(nèi)存逃逸2.什么是逃逸分析3.小結(jié)4.逃逸分析案例1.函數(shù)返回局部指針變量2.interface類(lèi)型逃逸1.interface產(chǎn)生逃逸2.指向棧對(duì)象的指針不能在堆中3.閉包產(chǎn)生逃逸4.變量大小不確定及??臻g不足引發(fā)逃逸5.總結(jié)
1.什么是內(nèi)存逃逸
在一段程序中,每一個(gè)函數(shù)都會(huì)有自己的內(nèi)存區(qū)域分配自己的局部變量,返回值,這些內(nèi)存會(huì)由編譯器在棧中進(jìn)行分配,每一個(gè)函數(shù)會(huì)分配一個(gè)棧幀,在函數(shù)運(yùn)行結(jié)束后銷(xiāo)毀,但是有些變量我們想在函數(shù)運(yùn)行結(jié)束后仍然使用,就需要把這個(gè)變量分配在堆上,這種從棧上逃逸到堆上的現(xiàn)象叫做內(nèi)存逃逸
2.什么是逃逸分析
雖然Go語(yǔ)言引入的Gc,GC機(jī)制會(huì)對(duì)堆上的對(duì)象進(jìn)行管理,當(dāng)某個(gè)對(duì)象不可達(dá)(沒(méi)有其他對(duì)象引用他),他將會(huì)被回收。雖然GC可以降低工作人員負(fù)擔(dān),但是GC也會(huì)給程序帶來(lái)性能損耗,當(dāng)堆內(nèi)存上有大量的堆內(nèi)存對(duì)象,就會(huì)給GC很大的壓力,雖然Go語(yǔ)言使用的是標(biāo)記清除算法,并且在此基礎(chǔ)上使用了三色標(biāo)記法和寫(xiě)屏障技術(shù),但是我們?cè)诙焉戏峙浯罅績(jī)?nèi)存,仍然會(huì)對(duì)GC造成很大壓力,Go引入了逃逸分析,就是想減少堆內(nèi)存的分配,可以在棧分配的內(nèi)存盡量分配在棧上
3.小結(jié)
逃逸分析就是在程序編譯階段根據(jù)代碼中的數(shù)據(jù)流,對(duì)代碼中哪些變量需要在棧上分配,哪些需要在對(duì)象分配的靜態(tài)分析方法,堆和棧相比,堆適合分配不可預(yù)知大小的內(nèi)存,但是付出代價(jià)是分配速度慢,容易產(chǎn)生碎片,棧分配十分快,棧分配只需要兩個(gè)指令Push和Release分配和釋放,而且堆分配需要先找一塊適合大小的內(nèi)存塊分配,需要垃圾回收釋放,所以逃逸分析可以更好的做內(nèi)存分配
Go語(yǔ)言的逃逸分析
src/cmd/compile/internal/gc/escape.go
pointerstostackobjectscannotbestoredintheheap:指向棧對(duì)象的指針不能存儲(chǔ)在堆中pointerstoastackobjectcannotoutlivethatobject:指向棧對(duì)象的指針不能超過(guò)該對(duì)象的存活期,指針不能在棧對(duì)象銷(xiāo)毀之后依然存活(例子:聲明的函數(shù)返回并銷(xiāo)毀了對(duì)象的棧幀,或者它在循環(huán)迭代中被重復(fù)用于邏輯上不同的變量)
既然逃逸分析是在編譯階段進(jìn)行的,那我們就可以通過(guò)gobuild-gcflga-m-ml查看逃逸分析結(jié)果
4.逃逸分析案例
1.函數(shù)返回局部指針變量
funcAdd(x,yint)*int{
res:=0
res=x+y
returnres
funcmain(){
Add(1,2)
.\pointer.go:4:2:resescapestoheap:
.\pointer.go:4:2:flow:~r2=res:
.\pointer.go:4:2:fromres(address-of)at.\pointer.go:6:9
.\pointer.go:4:2:fromreturnres(return)at.\pointer.go:6:2
.\pointer.go:4:2:movedtoheap:res
函數(shù)返回局部變量是一個(gè)指針變量,函數(shù)Add執(zhí)行結(jié)束,對(duì)應(yīng)棧幀就會(huì)銷(xiāo)毀,但是引用返回到函數(shù)外部,如果我們外部解析地址,就會(huì)導(dǎo)致程序訪(fǎng)問(wèn)非法內(nèi)存,所以經(jīng)過(guò)編輯器分析過(guò)后將其在堆上分配
2.interface類(lèi)型逃逸
1.interface產(chǎn)生逃逸
funcmain(){
str:="荔枝"
fmt.Println(str)
E:\GoStudy\src\HighBase\Escapegobuild-gcflags=-m-m-l./pointer.go
.\pointer.go:20:13:strescapestoheap:
.\pointer.go:20:13:flow:{storagefor...argument}={storageforstr}:
.\pointer.go:20:13:fromstr(spill)at.\pointer.go:20:13
.\pointer.go:20:13:from...argument(slice-literal-element)at.\pointer.go:20:13
.\pointer.go:20:13:flow:{heap}={storagefor...argument}:
.\pointer.go:20:13:from...argument(spill)at.\pointer.go:20:13
.\pointer.go:20:13:fromfmt.Println(...argument...)(callparameter)at.\pointer.go:20:13
.\pointer.go:20:13:...argumentdoesnotescape
.\pointer.go:20:13:strescapestoheap
str是main的一個(gè)局部變量,傳給fmt.Printl()之后逃逸,因?yàn)閒mt.Println()的入?yún)⑹莍nterface{}類(lèi)型,如果參數(shù)為interface{},那么編譯期間就很難確定參數(shù)類(lèi)型
2.指向棧對(duì)象的指針不能在堆中
我們把代碼改成這樣
funcmain(){
str:="蘇珊"
fmt.Println(str)
.\pointer.go:19:2:strescapestoheap:
.\pointer.go:19:2:flow:{storagefor...argument}=str:
.\pointer.go:19:2:fromstr(address-of)at.\pointer.go:20:14
.\pointer.go:19:2:fromstr(interface-converted)at.\pointer.go:20:14
.\pointer.go:19:2:from...argument(slice-literal-element)at.\pointer.go:20:13
.\pointer.go:19:2:flow:{heap}={storagefor...argument}:
.\pointer.go:19:2:from...argument(spill)at.\pointer.go:20:13
.\pointer.go:19:2:fromfmt.Println(...argument...)(callparameter)at.\pointer.go:20:13
.\pointer.go:19:2:movedtoheap:str
.\pointer.go:20:13:...argumentdoesnotescape
這次str也逃逸到堆上面了,在堆上面進(jìn)行分配,因?yàn)槿雲(yún)⑹莍nterface,變量str的地址被以實(shí)參的方式傳入fmt.Println被裝箱到一個(gè)interface{}
裝箱的形參變量要在堆上分配,但是還需要存儲(chǔ)一個(gè)棧上的地址,這和之前說(shuō)的第一條不符,所以str也會(huì)分配到堆上
3.閉包產(chǎn)生逃逸
funcIncrease()func()int{
n:=0
returnfunc()int{
n++
returnn
funcmain(){
in:=Increase()
fmt.Println(in())//1
E:\GoStudy\src\HighBase\Escapegobuild-gcflags-m-m-l./pointer.go
.\pointer.go:27:2:Increasecapturingbyref:n(addr=falseassign=truewidth=8)
.\pointer.go:28:9:funcliteralescapestoheap:
.\pointer.go:28:9:flow:~r0={storageforfuncliteral}:
.\pointer.go:28:9:fromfuncliteral(spill)at.\pointer.go:28:9
.\pointer.go:28:9:fromreturnfuncliteral(return)at.\pointer.go:28:2
.\pointer.go:27:2:nescapestoheap:
.\pointer.go:27:2:flow:{storageforfuncliteral}=n:
.\pointer.go:27:2:fromn(capturedbyaclosure)at.\pointer.go:29:3
.\pointer.go:27:2:fromn(reference)at.\pointer.go:29:3
.\pointer.go:27:2:movedtoheap:n
.\pointer.go:28:9:funcliteralescapestoheap
.\pointer.go:36:16:in()escapestoheap:
.\pointer.go:36:16:flow:{storagefor...argument}={storageforin()}:
.\pointer.go:36:16:fromin()(spill)at.\pointer.go:36:16
.\pointer.go:36:16:from...argument(slice-literal-element)at.\pointer.go:36:13
.\pointer.go:36:16:flow:{heap}={storagefor...argument}:
.\pointer.go:36:16:from...argument(spill)at.\pointer.go:36:13
.\pointer.go:36:16:fromfmt.Println(...argument...)(callparameter)at.\pointer.go:36:13
.\pointer.go:36:13:...argumentdoesnotescape
.\pointer.go:36:16:in()escap
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 星級(jí)酒店集團(tuán)管理辦法
- 血液中心全面質(zhì)量管理體系建設(shè)及程序文件解讀
- 華為后備梯隊(duì)管理辦法
- 公廁建設(shè)后續(xù)管理辦法
- 水輪機(jī)增效優(yōu)化技術(shù)-洞察及研究
- 傳播學(xué)領(lǐng)域的爭(zhēng)議、轉(zhuǎn)向及新聞傳播范疇探討
- 公益健康基金管理辦法
- 公文書(shū)寫(xiě)中的字體規(guī)范與設(shè)計(jì)原則
- 安全生產(chǎn)八不傷害心得體會(huì)
- 世界文化遺產(chǎn)申報(bào)
- GB/T 3672.2-2002橡膠制品的公差第2部分:幾何公差
- GB/T 18884.2-2015家用廚房設(shè)備第2部分:通用技術(shù)要求
- GB/T 12239-2008工業(yè)閥門(mén)金屬隔膜閥
- 軍標(biāo)類(lèi)型整理文檔
- 山東中醫(yī)藥大學(xué)2020-2021學(xué)年內(nèi)科護(hù)理學(xué)試題及答案1
- DB32T 4174-2021 城市居住區(qū)和單位綠化標(biāo)準(zhǔn)
- 基本原理與性能特點(diǎn)多自由度電磁軸承課件
- Q∕SY 1836-2015 鍋爐 加熱爐燃油(氣)燃燒器及安全聯(lián)鎖保護(hù)裝置檢測(cè)規(guī)范
- 北京輸變電工程標(biāo)準(zhǔn)工藝應(yīng)用圖冊(cè)(圖文并茂)
- 儀器使用記錄表
- 《汽車(chē)電工電子技術(shù)》全套教案(完整版)
評(píng)論
0/150
提交評(píng)論