欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

GopherCon SG 2019 "Understanding Allocations" 學(xué)習(xí)筆記

本篇是根據(jù) GopherCon SG 2019 “Understanding Allocations” 演講的學(xué)習(xí)筆記。

站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到扶風(fēng)網(wǎng)站設(shè)計(jì)與扶風(fēng)網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類(lèi)型包括:網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國(guó)際域名空間、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋扶風(fēng)地區(qū)。

Understanding Allocations: the Stack and the Heap - GopherCon SG 2019 - YouTube


理解分配:棧和堆

你的程序中有兩種內(nèi)存,棧內(nèi)存和堆內(nèi)存。

go 中,每個(gè) go 程都會(huì)有一個(gè)??臻g,整個(gè)程序有一個(gè)堆空間。


變量是在棧還是堆上

負(fù)責(zé)堆垃圾回收的 GC 會(huì)導(dǎo)致整個(gè)程序的延遲,而不僅僅是創(chuàng)建垃圾的部分。你可能會(huì)擔(dān)心你的代碼在堆中產(chǎn)生了多少垃圾。


什么時(shí)候需要優(yōu)化

要有 benchmarks 基準(zhǔn)來(lái)證明你的程序不夠快(有大量的堆內(nèi)存分配),夠快就不用多此一舉了。

你要先確保程序能正確運(yùn)作(業(yè)務(wù)處理),而不是先著重性能優(yōu)化。

在有大量指針+運(yùn)行快速的程序、清晰明了+但有點(diǎn)慢的程序之間,你應(yīng)該選擇后者。


普通類(lèi)型參數(shù)傳遞

第5行進(jìn)入squre函數(shù)

函數(shù)和局部變量被擠壓入棧,一個(gè)函數(shù)為一個(gè)堆棧幀。


squre函數(shù)執(zhí)行完

執(zhí)行完成后,你會(huì)發(fā)現(xiàn)黑線(只是用于區(qū)分)向上移,上方內(nèi)容為有效內(nèi)容,下方內(nèi)容為無(wú)效內(nèi)容(過(guò)期而不再使用


第6行執(zhí)行println函數(shù)

go 聲明了新的內(nèi)存部分,我們有了新的堆棧幀用于打印行,黑線下移。

通俗的來(lái)講,??臻g會(huì)進(jìn)行自我清理,任何變量都會(huì)被清理干凈,空間會(huì)被重復(fù)使用。


指針類(lèi)型參數(shù)傳遞

第4行聲明變量

main 函數(shù)和變量 n 被壓入棧。


第5行進(jìn)入inc函數(shù)

inc 函數(shù)和變量 x 被壓入棧,屬于另一個(gè)堆棧幀,黑線下移。傳入的變量是 n 的地址。


inc函數(shù)執(zhí)行完

黑線上移,n 被修改了值。并沒(méi)有什么問(wèn)題。


執(zhí)行println函數(shù)


總結(jié)

雖然使用了指針傳參,但這種情況下它能夠留在棧上,即共享向下傳遞時(shí),通常留在棧空間上。(主函數(shù)將自己的變量傳給子函數(shù))


函數(shù)返回引用

第4行進(jìn)入answer函數(shù)前

編譯器推斷出 n 是 int 的指針類(lèi)型,賦初值 nil 等待函數(shù)返回結(jié)果。


進(jìn)入函數(shù)

在函數(shù)內(nèi)部聲明了變量并初始化,并返回了變量的內(nèi)存地址。


執(zhí)行println函數(shù)

致命的問(wèn)題

你會(huì)發(fā)現(xiàn),我明明沒(méi)有進(jìn)行賦值修改的操作,但卻破壞了原有的值。原因在于

  • 調(diào)用 answer 函數(shù)的時(shí)候,假如我們把聲明的變量 x 放在棧空間,返回變量的地址。
  • 那么 main 函數(shù)中的 n 會(huì)拿到 x 的地址,當(dāng) answer 方法退出時(shí)(黑線上移),該堆棧幀已過(guò)期,但是 n 還引用著 x
  • 我們知道堆棧的空間是可以被重復(fù)利用的,那么下一次執(zhí)行其他函數(shù)或者聲明變量的時(shí)候,那塊過(guò)期的內(nèi)存區(qū)域就會(huì)被重新使用,修改為其他值。
  • 案例中調(diào)用 println,黑線下移,產(chǎn)生新的堆棧幀,原先 x 標(biāo)識(shí)符被替換成了 a,修改 a 的值等同修改了 n 地址解引用后的值。這是非常致命的錯(cuò)誤。

解決的方法

為了解決上述致命的問(wèn)題,被聲明初始化的 x 變量就需要“逃逸”到堆空間中。這樣其他無(wú)關(guān)函數(shù)就不會(huì)對(duì)它的值產(chǎn)生影響。

共享向上傳遞時(shí),通常留在堆空間上。(子函數(shù)將自己的變量傳給主函數(shù),引用)

Escape Analysis

編譯器怎么判斷的

變量只在函數(shù)里工作,那就分配到棧空間上。如果編譯器不能證明函數(shù)返回后聲明過(guò)的變量是否被引用,那必須將其分配到堆空間上。


詢問(wèn)編譯器

查看構(gòu)建指令,可以提供一個(gè) -gcflags 的可選參數(shù),傳遞給 go tool compile 工具

查詢 go tool compile -h,得知參數(shù) -m 可以輸出編譯器的優(yōu)化決定(變量放在棧還是堆上)

執(zhí)行 go build -gcflags "-m" 獲取到下面的結(jié)果

總結(jié)

什么時(shí)候會(huì)把變量分配在堆內(nèi)存上

  • 函數(shù)返回退出后聲明過(guò)的變量依舊被引用著。
  • 變量初始化值大小過(guò)大無(wú)法分配進(jìn)棧。
  • 不知道變量值的具體大小,比如切片。

做個(gè)判斷

看看前面總結(jié)的第一點(diǎn)和第三點(diǎn)。明顯可以知道右邊那個(gè)是分配在棧上,而左邊那個(gè)分配在堆上。


思考io.Reader接口

io 標(biāo)準(zhǔn)庫(kù)里有個(gè) Reader 接口,你應(yīng)該知道為什么官方要用前者替換后者了吧。如果使用后者,會(huì)在堆上產(chǎn)生大量的垃圾,造成程序遲鈍。前者則符合向下傳遞思想,變量通常分配在棧空間上。


最后

不要猜想,多用工具!

網(wǎng)站名稱(chēng):GopherCon SG 2019 "Understanding Allocations" 學(xué)習(xí)筆記
網(wǎng)站地址:http://chinadenli.net/article36/dsoissg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)手機(jī)網(wǎng)站建設(shè)網(wǎng)站建設(shè)、App開(kāi)發(fā)網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)