日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Go1.20arena能手動管理內(nèi)存了,怎么用?

大家好,我是煎魚。

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、余江ssl等。為上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的余江網(wǎng)站制作公司

最近 Go1.20 中的手動管理內(nèi)存受到了很多人的關(guān)注。眾所周知,Go 是一門帶垃圾回收(GC)的編程語言,可以進行自動的內(nèi)存申請、釋放等內(nèi)存操作。

帶 GC 能簡化編程時的心智成本,也保證了內(nèi)存的安全。我們說 “一般”,也就是有例外。人們說六個,一般都有七個。

Go 的例外就出現(xiàn)了。

Go1.20 arena

新版本 Go1.20,基于 Google 自身的需求,快速通過了實踐,正式支持了 arena,能夠?qū)崿F(xiàn)手動的內(nèi)存管理(當前是實驗性特性)。

現(xiàn)在可以通過 GOEXPERIMENT=arenas 環(huán)境變量啟用:

GOEXPERIMENT=arenas go run main.go

該特性可以讓程序員手動的從一個連續(xù)的內(nèi)存區(qū)域申請、分配一組內(nèi)存對象,也可以一次性的釋放。

重點是可以手動管理內(nèi)存。

提供的 arena API

  • NewArena:創(chuàng)建一個新的 arena 內(nèi)存空間。
  • Free:釋放 arena 及其關(guān)聯(lián)對象。
  • New:基于 arena,創(chuàng)建新對象。
  • MakeSlice:基于 arena,創(chuàng)建新切片。
  • Clone:克隆一個 arena 的對象,并移動到內(nèi)存堆上。

一些 arena 例子

以下案例和性能測試是基于 uptrace 在 Golang memory arenas [101 guide][1] 中分享的 arena 例子,本處進行引用,我就不自創(chuàng)一份了。

很適合在初學(xué)時作為 Demo 使用,打算也留著自己下次用時結(jié)合文檔翻一番。

arena.NewArena

一起來快速入門。代碼如下:

import "arena"

type T struct{
Foo string
Bar [16]byte
}

func processRequest(req *http.Request) {
// 在函數(shù)開頭創(chuàng)建一個 arena
mem := arena.NewArena()
// 在函數(shù)結(jié)束時釋放 arena
defer mem.Free()

// 從申請的 arena 中申請一些對象
for i := 0; i < 10; i++ {
obj := arena.New[T](mem "T")
}

// 從申請的 arena 中申請切片對象(指定長度和容量)
slice := arena.MakeSlice[T](mem, 100, 200 "T")
}

arena.Clone

如果要單獨使用某個申請出來的對象。可以借助 Clone 方法進行單獨處理。

如下代碼:

// 創(chuàng)建一個 arena
mem := arena.NewArena()

obj1 := arena.New[T](mem "T") // 分配一個 arena 對象
obj2 := arena.Clone(obj1) // 拷貝一個 arena 上的對象,移動到內(nèi)存堆上
fmt.Println(obj2 == obj1) // 即使是基于拷貝出來的,兩者并不完全等價

// 釋放 arena,obj1 不可使用,obj2 可正常使用
mem.Free()

釋放了最早申請的 arena,Clone 方法在這里將會把 obj1 拷貝到新的內(nèi)存堆上,再賦值給 obj2。后續(xù)要單獨用 obj2 就可以繼續(xù)使用。

reflect.ArenaNew

也可以結(jié)合 arena 和 reflect 兩個標準庫來進行使用。如下代碼:

var typ = reflect.TypeOf((*T)(nil)).Elem()

mem := arena.NewArena()
defer mem.Free()

value := reflect.ArenaNew(mem, typ)
fmt.Println(value.Interface().(*T))

arena.MakeSlice

該方法的常規(guī)用法:

arena.MakeSlice[string](mem, length, capacity "string")

如果需要申請一個新切片并追加元素:

slice := arena.MakeSlice[string](mem, 0, 0 "string")
slice = append(slice, "")

需要注意的是,arena 目前不支持 map。但你可以通過泛型來實現(xiàn)類似的效果。

arena.String

原則上 arena 不支持 string。但是我們依然可以通過 unsafe.String 方法的騷操作來變相實現(xiàn)。

如下代碼:

src := "腦子進煎魚了"

mem := arena.NewArena()
defer mem.Free()

bs := arena.MakeSlice[byte](mem, len(src "byte"), len(src))
copy(bs, src)
str := unsafe.String(&bs[0], len(bs))

在申請的 arena 釋放后,該對應(yīng)的 string 就無法使用了,需要特別注意。

性能表現(xiàn)

這個允許手工管理內(nèi)存的 arena 的特性是來源于內(nèi)部,提案也是一路綠燈通過。(懂得懂)。

自述已經(jīng)為 Google 許多應(yīng)用節(jié)省了高達 15% 的 CPU 和內(nèi)存使用量,主要原因是減少了垃圾收集 CPU 時間和堆內(nèi)存使用量。

經(jīng)過在 vmihailenco/golang-memory-arenas[2] 項目中實際的性能對比。

沒有用 arena:

/usr/bin/time go run arena_off.go
77.27user 1.28system 0:07.84elapsed 1001%CPU (0avgtext+0avgdata 532156maxresident)k
30064inputs+2728outputs (551major+292838minor)pagefaults 0swaps

使用了 arena:

GOEXPERIMENT=arenas /usr/bin/time go run arena_on.go
35.25user 5.71system 0:05.09elapsed 803%CPU (0avgtext+0avgdata 385424maxresident)k
48inputs+3320outputs (417major+63931minor)pagefaults 0swaps

使用了 arena 的代碼運行速度更快,且使用的內(nèi)存更少。

總結(jié)

Go 的各位大大們在性能優(yōu)化中,不斷地試圖壓榨 Go 的潛力。現(xiàn)在已經(jīng)到了手工管理內(nèi)存的階段了。

實際的測試結(jié)果來看,是有作用的。

有興趣的小伙伴可以在 Go1.20 起就開始試用。不過需要注意,該特性由于發(fā)現(xiàn)了嚴重的 API 問題(想把 arena 應(yīng)用到其他的標準庫中,但這是個大事件),社區(qū)還需要認真思考后續(xù)的發(fā)展,現(xiàn)階段處于處于停滯狀態(tài)。

從這次提案來看,真的是,內(nèi)部需求一路猛如虎,直接沖上 master。外部需求就畏畏縮縮了。真雙標?


新聞標題:Go1.20arena能手動管理內(nèi)存了,怎么用?
文章URL:http://www.5511xx.com/article/djehgig.html