說說golang的對象池sync.Pool

網(wǎng)上關(guān)于sync.Pool的源碼分析的文章比較多,本文的重點(diǎn)不在于源碼分析,而在于簡單易懂的介紹一下sync.Pool的內(nèi)部實(shí)現(xiàn)方式,如果想要了解更多,可以看下參考中的文章

本文基于Go1.14
參考:https://www.cnblogs.com/qcrao-2018/p/12736031.html

先看下Pool的整體結(jié)構(gòu):
整個結(jié)構(gòu)實(shí)際上可以簡化為每一個PoolLocal實(shí)現(xiàn)了一個雙向列表,其中每個節(jié)點(diǎn)用數(shù)組的方式來實(shí)現(xiàn)了循環(huán)列表。

  • 雙向鏈表是為了可不限長度的擴(kuò)展。
  • 雙向鏈表中每個節(jié)點(diǎn)都保存一個數(shù)組來實(shí)現(xiàn)循環(huán)隊(duì)列,數(shù)組長度初始為8,每新增一個節(jié)點(diǎn),數(shù)組長度變?yōu)樵瓉淼?倍(直到最大限制),以此來動態(tài)的適應(yīng)對象的數(shù)量,并且不至于讓鏈表過長。
  • private,PoolLocal數(shù)組是為了避免上鎖,以提升性能。
  • pad涉及cpu緩存,參考:http://m.itdecent.cn/p/dc4b5562aad2

第二張圖很形象的說明了多個P之間的對象共享,如果P1/P2/P3內(nèi)部沒有可用對象了怎么辦?從P0的隊(duì)尾取對象,而P0自身是從對頭,從而避免了鎖競爭。

當(dāng)然還有很多細(xì)節(jié),比如維護(hù)所有Pool的AllPools和oldPools,比如victim和local,旨在垃圾回收和對象分配之間做一個平衡,防止對象池中對象一次性全部回收造成突發(fā)的大量新對象帶來內(nèi)存申請等等。這些細(xì)節(jié)可以看源碼慢慢去體會。

image.png
image.png

是不是看著比較暈,其實(shí)是內(nèi)部各種套娃,核心思想都是為了盡可能減少并發(fā)導(dǎo)致的資源競爭以及有效利用cpu緩存。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容