go語言-變量逃逸

go變量逃逸

go語言的一個變量是在堆上分配,還是在棧上分配,是經過golang編譯器的逃逸分析之後得出結論的,這一切都是編譯器幫我們完成的。

什麼是變量逃逸

簡單來說,變量逃逸就是一個變量由棧逃逸到堆的過程。
我們知道c和c++變量的內存分配和銷燬都是需要程序員手動來執行的。
舉個栗子,在函數內部定義了一個局部變量,然後返回這個局部變量的地址,這些局部變量是在棧上分配的(靜態分配內存),一旦函數執行完成,變量佔據的內存被銷燬,任何這個返回值的動作,比如解引用,都會擾亂程序的執行,甚至導致程序崩潰。
或者,我們使用new函數構造一個變量(動態分配內存),然後返回變量的地址,因爲變量是在堆上創建的,所以函數執行完成退出時變量不會被銷燬。但是調用者很可能忘記delete,也就會發生內存泄露。
綜上,變量的逃逸分析就是決定一個變量是分配在堆上還是棧上。

爲什麼要逃逸分析

逃逸分析是爲了合理的分配變量到它該去的地方,如果一個變量在函數執行完成後沒有別的用處,那麼就該分配到棧上,畢竟棧上的內存分配比堆上的快很多,相反,如果變量在函數結束後還有其他引用,那就該分配到堆上。
當然,如果變量都分配到堆上,堆不像棧可以自動清理,堆會引起go頻繁的進行垃圾回收,而垃圾回收會佔用比較大的系統開銷。堆和棧相比,堆適合不可預知大小的內存分配,但分配速度較慢,而且會形成內存碎片,最後還需要gc進行釋放。棧內存分配就比較快了,只需要CPU的兩個命令即可實現分配和釋放。
通過逃逸分析,可以儘量把哪些不需要分配到堆上的變量直接分配到棧上,堆上的變量減少了,會減輕分配堆內存的開銷,同時也會減少gc的壓力,提供程序的運行速度。

編譯器的逃逸分析

go編譯器逃逸分析的基本原則是,若個一個函數返回對一個變量的引用,那麼它就會發生逃逸。如果編譯器對代碼進行分析後,發現函數返回後,變量不在被引用,那麼還是分配到棧上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章