Go 要違背初心嗎?新提案:手動(dòng)管理內(nèi)存
背景
由于手動(dòng)管理內(nèi)存普遍會(huì)給程序員帶來(lái)一定的心智負(fù)擔(dān),提高一門(mén)編程語(yǔ)言的入門(mén)門(mén)檻(還記得大學(xué)寫(xiě) OC 時(shí)經(jīng)常有同學(xué)寫(xiě)著寫(xiě)崩了...)。
對(duì)應(yīng)到 Go 語(yǔ)言上,他是一門(mén)帶垃圾回收的編程語(yǔ)言。也就是說(shuō)不需要程序員手動(dòng)的去管理、釋放程序的內(nèi)存。
無(wú)需手動(dòng)管理也是 Go 核心開(kāi)發(fā)團(tuán)隊(duì)一直引以為傲的特性之一。
最近有人發(fā)起了一個(gè)新提案《proposal: arena: new package providing memory arenas》,引起了非常廣泛的討論。
如下圖:
接下來(lái)我們將面向該提案進(jìn)行學(xué)習(xí)和了解。
新提案
本提案所提到的 Arena,指的是一種從一個(gè)連續(xù)的內(nèi)存區(qū)域分配一組內(nèi)存對(duì)象的方式。優(yōu)點(diǎn)是 arena 中的對(duì)象分配通常比一般的內(nèi)存分配更有效率,所分配的對(duì)象可以一次性釋放,以此達(dá)到內(nèi)存管理或垃圾收集的開(kāi)銷最小。
其建議在 Go 的標(biāo)準(zhǔn)庫(kù)中支持 arena。標(biāo)準(zhǔn) API 如下:
這一實(shí)踐已經(jīng)在 Google 得到了應(yīng)用,且在一些大型應(yīng)用程序中節(jié)省了高達(dá) 15% 的CPU和內(nèi)存使用,這主要是由于減少了垃圾收集的CPU時(shí)間和堆內(nèi)存使用所帶來(lái)的效果。
arena 若成為標(biāo)準(zhǔn)庫(kù)的使用的例子:
手動(dòng)調(diào)用 arena.New? 方法分配 arena 內(nèi)存,再調(diào)用 Free 方法進(jìn)行釋放。
當(dāng)然,一般提案中所提到的 arena 并不會(huì)在一門(mén)帶垃圾回收的編程語(yǔ)言中實(shí)現(xiàn)。因?yàn)闀?huì)操作到內(nèi)存就有可能會(huì)不安全,不符合帶垃圾回收的語(yǔ)言定義。
該庫(kù)底層采取了動(dòng)態(tài)檢查來(lái)確保 arena 釋放內(nèi)存的操作是安全的。若出現(xiàn)異常情況,就會(huì)終止釋放。
爭(zhēng)論
圍繞這這個(gè)新的提案,評(píng)論區(qū)的網(wǎng)友們爭(zhēng)議的非常多。有的會(huì)疑惑,為什么一定要放在標(biāo)準(zhǔn)庫(kù),放第三方庫(kù)不行嗎?
實(shí)際上在第三方庫(kù)中很難安全地做到這一點(diǎn),因?yàn)橐粋€(gè)在 arena 庫(kù)中分配的變量,他包含指向外部的內(nèi)存指針,要確保性能下讓 GC 知道他,否則可能會(huì)導(dǎo)致錯(cuò)誤的釋放。
當(dāng)然,也有人提出,這 Go 就變成像 C++ 一樣,忘記 free、重復(fù) free、提前 free,與 Go 原先標(biāo)榜的簡(jiǎn)潔相差甚遠(yuǎn)。
總結(jié)
現(xiàn)階段該提案還在積極探討的階段,原型代碼也已經(jīng)提交《runtime: prototype CL showing possible implementation of arenas》有興趣的小伙伴可以抽時(shí)間看看。
這個(gè)提案爭(zhēng)議較大,你很難說(shuō)他是一個(gè)庫(kù),還是一個(gè)語(yǔ)言的根本性變更。你一旦在原生標(biāo)準(zhǔn)庫(kù)支持了,其他關(guān)聯(lián)的也必然會(huì)支持其 API,自然而然就植入進(jìn)去了,與 “unsafe” 標(biāo)準(zhǔn)庫(kù)定位一致,都是不安全的因素。
大家怎么看?