欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

GoLang逃逸分析講解

 更新時(shí)間:2022年12月15日 10:50:03   作者:上后左愛  
我們都知道go語言中內(nèi)存管理工作都是由Go在底層完成的,這樣我們可以不用過多的關(guān)注底層的內(nèi)存問題。本文主要總結(jié)一下?Golang內(nèi)存逃逸分析,需要的朋友可以參考以下內(nèi)容,希望對大家有幫助

概念

當(dāng)一個(gè)對象的指針在被多個(gè)方法或者線程引用,稱為逃逸分析, 逃逸分析決定一個(gè)變量分配在堆上還是棧上, 當(dāng)然是否發(fā)生逃逸是由編譯器決定的

分配棧和堆上變量的問題

1.局部變量在棧上(靜態(tài)分配),函數(shù)執(zhí)行完畢后,自動被?;厥?,導(dǎo)致其他對此變量引用出現(xiàn)painc null 指針異常, 棧用戶態(tài)實(shí)現(xiàn)goroutine 作為執(zhí)行上下文

2.將變量 new 方式分配在堆上(動態(tài)分配),堆上有個(gè)特點(diǎn),變量不會被刪除,但是會造成內(nèi)存異常

// 如下代碼導(dǎo)致 程序崩潰, 調(diào)用棧獲取危險(xiǎn)的懸掛指針
int *foo ( void)   
{     
int t = 3;
return &t;
} 

1. 棧上分配內(nèi)存好處: 一般棧內(nèi)存 2-4 MB
a. 回收快: 減少GC壓力,當(dāng)函數(shù)返回回收資源。不需要標(biāo)記清除
b. 分配快棧分配比堆快,不會有內(nèi)存碎片
c. 并發(fā)快, 清除同步,如果定義對象上有同步鎖,卻只有一個(gè)線程訪問,此時(shí)逃逸分析機(jī)器碼 去掉同步鎖

總結(jié): 逃逸分析目標(biāo):盡可能的使用棧分配內(nèi)存 go build -gcflags ‘-m -N -l’ 方式編譯逃逸分析結(jié)果

逃逸分析準(zhǔn)則

如果一個(gè)函數(shù)返回對變量的引用,那么他就發(fā)生逃逸

  • 函數(shù)外部沒有引用,優(yōu)先分配到棧中(指向棧對象指針不能存在堆中)-- 該指針指向無效值或錯(cuò)誤的內(nèi)存值
  • 函數(shù)外部存在引用,必定分配到堆中(指向棧對象指針不能在棧對象回收后存活-- 指向的內(nèi)存不合法)

CCN_ProLang/CoreGo/GoreGo 下面有對應(yīng)的文檔參考

逃逸分析大致思路

1.最重要函數(shù) escape.go

$GOROOT/src/cmd/compile/internal/gc/escape.go

1. 首先構(gòu)建一個(gè)有向無環(huán)圖加權(quán)圖,頂點(diǎn)(語句和表達(dá)式分配的變量),邊(代表變量之間的賦值關(guān)系)
2. 遍歷該有向加權(quán)圖,圖中違反上面兩個(gè)不變條件的賦值路徑,算法還記錄每個(gè)函數(shù)的參數(shù)到堆的數(shù)據(jù)流和其返回值的數(shù)據(jù)流
權(quán)重

// p =&q -1 // 最低值
// p =q 0
// p = *q // 解引用 1
// p = **q 2

示例: root =&L , L 節(jié)點(diǎn)的指針指向root, 因此 root有一條邊,src 就是L,該權(quán)重就是 -1

3. 逃逸分析: 分析 分配內(nèi)存地方與使用 是否發(fā)生逃逸
4. go build -gcflags = "-m -m -m -m -W -W -N -l"

1. 當(dāng)函數(shù)中變量返回值, 它將不可能分配在棧上

2.在循環(huán)內(nèi)被重新賦值的變量大部分場景分配在堆上

3.在閉包外聲明的變量在閉包內(nèi)賦值失效后,需要分配在堆上

是否發(fā)生逃逸,這一點(diǎn)使用編譯器決定的。導(dǎo)致后果:1. GC頻繁導(dǎo)致CPU壓力大 2.導(dǎo)致性能下降很大

1. 一些逃逸案例:
2. 函數(shù)返回變量取地址 導(dǎo)致逃逸
func GetUserInfo(userInfo UserData) *UserData{
   // 編譯器判斷外部使用 發(fā)生逃逸 ,傳入的實(shí)參對象 取地址類似復(fù)制一份
	return &userInfo
}
//修改 將入?yún)⑿薷某芍羔? 中間沒有新結(jié)構(gòu)體沒有變化 沒有發(fā)生逃逸
func GetUserInfo(userInfo *UserData) *UserData {
		return userInfo
}
案例二:不確定類型逃逸
func MyPrintLn(one interface{}) (n int, err error){
	var userInfo = new(User)
	userInfo.name = one // 泛型賦值逃逸 類型轉(zhuǎn)換時(shí)候發(fā)生逃逸
	return
}
變量確定具體類型
示例三: 間接變量賦值 閉包
var {
     UserOne User // 值對象
     userTwo = new(User) // 引用對象
}
userOne.name = "one" // 不逃逸
userTwo.name = "two" // 逃逸
userOne.age = new(int) // 不逃逸
userTwo.age = new(int) // 逃逸 引用對象在進(jìn)行引用對象 只能分配堆上
引用對象: 編譯器先分析器userTwo 對象分配到堆上,成員變量name,age 引用類型,保證不出現(xiàn)在棧上 導(dǎo)致對象userTwo 被回收 所有 name,age 需要逃逸
優(yōu)化建議: 不要將引用對象賦值給引用對象

總結(jié)

必然不會發(fā)生逃逸的情況:

1. 指針被沒有發(fā)生逃逸的變量引用

2. 僅僅在函數(shù)被對變量進(jìn)行取地址操作,沒有將指針傳出

一定逃逸

構(gòu)造函數(shù)new/make 返回的指針變量一定逃逸

2. 被已經(jīng)逃逸指針變量引用指針,一定發(fā)生逃逸

3.指針類型是slice,map,chan 引用指針一定發(fā)生逃逸

Maybe 逃逸

將指針作為入?yún)鹘o別的函數(shù),這里看指針在被傳入函數(shù)的處理過程,如果發(fā)生上邊三種情況會逃逸,否則不會

到此這篇關(guān)于GoLang逃逸分析講解的文章就介紹到這了,更多相關(guān)Go逃逸內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在go中進(jìn)行單元測試的案例分享

    在go中進(jìn)行單元測試的案例分享

    這篇文章主要介紹了使用Go進(jìn)行單元測試的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • golang croncli 定時(shí)器命令詳解

    golang croncli 定時(shí)器命令詳解

    定時(shí)器是執(zhí)行任務(wù)時(shí)的常用功能,配置系統(tǒng)的定時(shí)任務(wù)太麻煩,所以就想用golang簡單實(shí)現(xiàn)一個(gè)定時(shí)器命令,包括定時(shí)器命令格式、定時(shí)執(zhí)行命令的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧
    2022-03-03
  • GO接收GET/POST參數(shù)及發(fā)送GET/POST請求的實(shí)例詳解

    GO接收GET/POST參數(shù)及發(fā)送GET/POST請求的實(shí)例詳解

    這篇文章主要介紹了GO接收GET/POST參數(shù)及發(fā)送GET/POST請求,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • golang敏感詞過濾的實(shí)現(xiàn)

    golang敏感詞過濾的實(shí)現(xiàn)

    本文主要介紹了golang敏感詞過濾的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • golang 如何實(shí)現(xiàn)HTTP代理和反向代理

    golang 如何實(shí)現(xiàn)HTTP代理和反向代理

    這篇文章主要介紹了golang 實(shí)現(xiàn)HTTP代理和反向代理的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go語言os包用法詳解

    Go語言os包用法詳解

    本文主要介紹了Go語言os包用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • golang中單機(jī)鎖的具體實(shí)現(xiàn)詳解

    golang中單機(jī)鎖的具體實(shí)現(xiàn)詳解

    這篇文章主要為大家詳細(xì)介紹了golang中單機(jī)鎖的具體實(shí)現(xiàn)的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • 使用Golang快速構(gòu)建出命令行應(yīng)用程序

    使用Golang快速構(gòu)建出命令行應(yīng)用程序

    在日常開發(fā)中,大家對命令行工具(CLI)想必特別熟悉了,如果說你不知道命令工具,那你可能是個(gè)假開發(fā)。每天都會使用大量的命令行工具,例如最常用的Git、Go、Docker等,這篇文章主要介紹了使用Golang快速構(gòu)建出命令行應(yīng)用程序,需要的朋友可以參考下
    2023-02-02
  • Go并發(fā)與鎖的兩種方式該如何提效詳解

    Go并發(fā)與鎖的兩種方式該如何提效詳解

    如果沒有鎖,在我們的項(xiàng)目中,可能會存在多個(gè)goroutine同時(shí)操作一個(gè)資源(臨界區(qū)),這種情況會發(fā)生競態(tài)問題(數(shù)據(jù)競態(tài)),下面這篇文章主要給大家介紹了關(guān)于Go并發(fā)與鎖的兩種方式該如何提效的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • go語言中int和byte轉(zhuǎn)換方式

    go語言中int和byte轉(zhuǎn)換方式

    這篇文章主要介紹了go語言中int和byte轉(zhuǎn)換方式,需要的朋友可以參考下
    2018-11-11

最新評論