欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Gosync.Pool的原理及作用是什么

本篇內(nèi)容主要講解“Go sync.Pool的原理及作用是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Go sync.Pool的原理及作用是什么”吧!

為莊河等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及莊河網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站建設(shè)、成都網(wǎng)站制作、莊河網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!

使用方式

sync.Pool 使用很簡單,但是想用對卻很麻煩,因為你有可能看到網(wǎng)上一堆錯誤的示例,各位同學(xué)在搜索 sync.Pool 的使用例子時,要特別注意。

sync.Pool 是一個內(nèi)存池。通常內(nèi)存池是用來防止內(nèi)存泄露的(例如C/C++)。sync.Pool 這個內(nèi)存池卻不是干這個的,帶 GC 功能的語言都存在垃圾回收 STW 問題,需要回收的內(nèi)存塊越多,STW 持續(xù)時間就越長。如果能讓 new 出來的變量,一直不被回收,得到重復(fù)利用,是不是就減輕了 GC 的壓力。

正確的使用示例(下面的demo選自gin)

func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {    c := engine.pool.Get().(*Context)
    c.writermem.reset(w)
    c.Request = req
    c.reset()

    engine.handleHTTPRequest(c)

    engine.pool.Put(c)}

一定要注意的是:是先 Get 獲取內(nèi)存空間,基于這個內(nèi)存做相關(guān)的處理,然后再將這個內(nèi)存還回(Put)到 sync.Pool。

Pool 結(jié)構(gòu)

Go sync.Pool的原理及作用是什么

sync.Pool 全景圖

源碼圖解

Go sync.Pool的原理及作用是什么

Pool.Get

Go sync.Pool的原理及作用是什么

Pool.Put

簡單點可以總結(jié)成下面的流程:

Go sync.Pool的原理及作用是什么

Pool.Get 流程

Go sync.Pool的原理及作用是什么

Pool.Put流程

Go sync.Pool的原理及作用是什么

Pool GC 流程

Sync.Pool 梳理

Pool 的內(nèi)容會清理?清理會造成數(shù)據(jù)丟失嗎?

Go 會在每個 GC 周期內(nèi)定期清理 sync.Pool 內(nèi)的數(shù)據(jù)。

要分幾個方面來說這個問題。

  1. 已經(jīng)從 sync.Pool Get 的值,在 poolClean 時雖說將 pool.local 置成了nil,Get 到的值依然是有效的,是被 GC 標(biāo)記為黑色的,不會被 GC回收,當(dāng) Put 后又重新加入到 sync.Pool 中

  2. 在第一個 GC 周期內(nèi) Put 到 sync.Pool 的數(shù)值,在第二個 GC 周期沒有被 Get 使用,就會被放在 local.victim 中。如果在 第三個 GC 周期仍然沒有被使用就會被 GC 回收。

runtime.GOMAXPROCS 與 pool 之間的關(guān)系?

s := p.localSize
l := p.localif uintptr(pid) < s {
    return indexLocal(l, pid), pid
}if p.local == nil {
    allPools = append(allPools, p)
}// If GOMAXPROCS changes between GCs, we re-allocate the array and lose the old one.size := runtime.GOMAXPROCS(0)
local := make([]poolLocal, size)
atomic.StorePointer(&p.local, unsafe.Pointer(&local[0])) // store-releaseruntime_StoreReluintptr(&p.localSize, uintptr(size))     // store-release

runtime.GOMAXPROCS(0) 是獲取當(dāng)前最大的 p 的數(shù)量。sync.Pool 的 poolLocal 數(shù)量受 p 的數(shù)量影響,會開辟 runtime.GOMAXPROCS(0) 個 poolLocal。某些場景下我們會使用 runtime.GOMAXPROCS(N) 來改變 p 的數(shù)量,會使 sync.Pool 的 pool.poolLocal 釋放重新開辟新的空間。

為什么要開辟 runtime.GOMAXPROCS 個 local?

pool.local 是個 poolLocal 結(jié)構(gòu),這個結(jié)構(gòu)體是 private + shared鏈表組成,在多 goroutine 的 Get/Put 下是有數(shù)據(jù)競爭的,如果只有一個 local 就需要加鎖來操作。每個 p 的 local 就能減少加鎖造成的數(shù)據(jù)競爭問題。

New() 的作用?假如沒有 New 會出現(xiàn)什么情況?

從上面的 pool.Get 流程圖可以看出來,從 sync.Pool 獲取一個內(nèi)存會嘗試從當(dāng)前 private,shared,其他的 p 的 shared 獲取或者 victim 獲取,如果實在獲取不到時,才會調(diào)用 New 函數(shù)來獲取。也就是 New() 函數(shù)才是真正開辟內(nèi)存空間的。New() 開辟出來的的內(nèi)存空間使用完畢后,調(diào)用 pool.Put 函數(shù)放入到 sync.Pool 中被重復(fù)利用。

如果 New 函數(shù)沒有被初始化會怎樣呢?很明顯,sync.Pool 就廢掉了,因為沒有了初始化內(nèi)存的地方了。

先 Put,再 Get 會出現(xiàn)什么情況?

「一定要注意,下面這個例子的用法是錯誤的」

func main(){
    pool:= sync.Pool{
        New: func() interface{} {
            return item{}
        },
    }
    pool.Put(item{value:1})
    data := pool.Get()
    fmt.Println(data)
}

如果你直接跑這個例子,能得到你想像的結(jié)果,但是在某些情況下就不是這個結(jié)果了。

在 Pool.Get 注釋里面有這么一句話:“Callers should not assume any relation between values passed to Put and the values returned by Get.”,告訴我們不能把值 Pool.Put 到 sync.Pool 中,再使用 Pool.Get 取出來,因為 sync.Pool 不是 map 或者 slice,放入的值是有可能拿不到的,sync.Pool 的數(shù)據(jù)結(jié)構(gòu)就不支持做這個事情。

前面說使用 sync.Pool 容易被錯誤示例誤導(dǎo),就是上面這個寫法。為什么 Put 的值 再 Get 會出現(xiàn)問題?

  • 情況1:sync.Pool 的 poolCleanup 函數(shù)在系統(tǒng) GC 時會被調(diào)用,Put 到 sync.Pool 的值,由于有可能一直得不到利用,被在某個 GC 周期內(nèi)就有可能被釋放掉了。

  • 情況2:不同的 goroutine 綁定的 p 有可能是不一樣的,當(dāng)前 p 對應(yīng)的 goroutine 放入到 sync.Pool 的值有可能被其他的 p 對應(yīng)的 goroutine 取到,導(dǎo)致當(dāng)前 goroutine 再也取不到這個值。

  • 情況3:使用 runtime.GOMAXPROCS(N) 來改變 p 的數(shù)量,會使 sync.Pool 的 pool.poolLocal 釋放重新開辟新的空間,導(dǎo)致 sync.Pool 被釋放掉。

  • 情況4:還有很多情況

只 Get 不 Put 會內(nèi)存泄露嗎?

使用其他的池,如連接池,如果取連接使用后不放回連接池,就會出現(xiàn)連接池泄露,「是不是 sync.Pool 也有這個問題呢?」

通過上面的流程圖,可以看出來 Pool.Get 的時候會嘗試從當(dāng)前 private,shared,其他的 p 的 shared 獲取或者 victim 獲取,如果實在獲取不到時,才會調(diào)用 New 函數(shù)來獲取,New 出來的內(nèi)容本身還是受系統(tǒng) GC 來控制的。所以如果我們提供的 New 實現(xiàn)不存在內(nèi)存泄露的話,那么 sync.Pool 是不會內(nèi)存泄露的。當(dāng) New 出來的變量如果不再被使用,就會被系統(tǒng) GC 給回收掉。

如果不 Put 回 sync.Pool,會造成 Get 的時候每次都調(diào)用的 New 來從堆棧申請空間,達(dá)不到減輕 GC 壓力。

使用場景

上面說到 sync.Pool 業(yè)務(wù)開發(fā)中不是一個常用結(jié)構(gòu),我們業(yè)務(wù)開發(fā)中沒必要假想某塊代碼會有強(qiáng)烈的性能問題,一上來就用 sync.Pool 硬懟。sync.Pool 主要是為了解決 Go GC 壓力過大問題的,所以一般情況下,當(dāng)線上高并發(fā)業(yè)務(wù)出現(xiàn) GC 問題需要被優(yōu)化時,才需要用 sync.Pool 出場。

使用注意點

  1. sync.Pool 同樣不能被復(fù)制。

  2. 好的使用習(xí)慣,從 pool.Get 出來的值進(jìn)行數(shù)據(jù)的清空(reset),防止垃圾數(shù)據(jù)污染。

?  

本文基于的 Go 源碼版本:1.16.2

?

參考鏈接

  1. 深度解密 Go 語言之 sync.Pool https://www.cnblogs.com/qcrao-2018/p/12736031.html

  2. 請問sync.Pool有什么缺點? https://mp.weixin.qq.com/s/2ZC1BWTylIZMmuQ3HwrnUg

  3. Go 1.13中 sync.Pool 是如何優(yōu)化的? https://colobu.com/2019/10/08/how-is-sync-Pool-improved-in-Go-1-13/

到此,相信大家對“Go sync.Pool的原理及作用是什么”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

新聞標(biāo)題:Gosync.Pool的原理及作用是什么
轉(zhuǎn)載注明:http://aaarwkj.com/article38/jjhjpp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、App設(shè)計、云服務(wù)器服務(wù)器托管、電子商務(wù)、動態(tài)網(wǎng)站

廣告

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

外貿(mào)網(wǎng)站制作
偷拍色图一区二区二区| 亚洲日本国产精品一区| 欧美香蕉视频一区二区| 国产精品国产三级国产普通话99| 剧情av一区二区在线| 亚洲国产色一区二区三区| 欧美成人午夜精品一区二区| 亚洲精品中文字幕一二三| 九九热在线免费观看精品视频 | 国产免费一级av剧情| 新午夜福利片在线观看| 亚洲av一区二区在线看| 亚洲黄色录像一区二区人妻黑人 | 97在线资源视频播放| 色婷婷一区二区三区网站| 日韩av一区二区免费在线观看| 内射性感黑丝少妇av| 熟女熟妇乱女乱妇综合网| 成人性生交大片免费看中文| 中文字幕有码av海量| 日本高清区一区二区三区四区五区| 国产亚洲精品视频免费| 91欧美日韩精品在线| 日韩一卡一卡在线观看| 欧美国产免费高清视频| 日本激情诱惑免费在线播放 | 日韩黄色精品中文视频| 一区二区高清中文字幕| 中文字幕亚洲精品视频| 麻豆国产97在线精品一区| 亚洲av不卡一区二区在线观看| 日本人妻三级精品久久| 国产丝袜美女一区二区| 日韩中文字幕一二一二区| 欧美国产日韩激情在线| 日韩精品一区二区三区都在看| 国产亚洲中文久久网久久| 一区二区三区毛片av网站| 欧美日韩国产综合一区二区| 国产亚洲精品久久久久久| 午夜视频在线观看91|