Go 語言社群正在討論名為的新提案。
根據提案的介紹,「Go arena」用於優化記憶體分配。arena 是一種從連續的記憶體區域分配一組記憶體物件的方法,其優點是從 arena 分配物件通常比一般記憶體分配更有效。更重要的是,arena 中的物件能夠用最少的記憶體管理或垃圾回收開銷一次釋放所有內容。
通常來說,arena 不會在具備垃圾回收的程式語言中實現,因為它們用於顯式釋放 arena 記憶體的操作不安全,所以不符合垃圾回收語意。不過此提案的實現使用了動態檢查來確保 arena 操作是安全的。此外還保證,如果 arena 操作不安全,程式將在任何不正確的行為發生之前終止。目前 Go 團隊已在 Google 內部實現並使用了 arena,結果顯示其為許多大型應用程式節省了高達 15% 的 CPU 和記憶體使用量,這主要是由於垃圾回收 CPU 時間和堆記憶體使用量的減少。
提案簡介
在 Go 標準庫中增加一個新的arena
包,arena
包可用於分配任意數量的 arena,可以從 arena 的記憶體中分配任意型別的物件,並且 arena 會根據需要自動增長大小。當一個 arena 中的所有物件不再使用時,可以顯式釋放該 arena 以有效地回收其記憶體,而無需進行常見的垃圾回收操作。我們要求此實現提供安全檢查,如果 arena 操作不安全,程式將在任何不正確的行為發生之前終止。 為了獲得最大的靈活性,API 能夠分配任何型別的物件和切片,包括可以在執行時通過反射生成的型別。
提案 API:
package arena
type Arena struct {
// contains filtered or unexported fields
}
// New allocates a new arena.
func New() *Arena
// Free frees the arena (and all objects allocated from the arena) so that
// memory backing the arena can be reused fairly quickly without garbage
// collection overhead. Applications must not call any method on this
// arena after it has been freed.
func (a *Arena) Free()
// New allocates an object from arena a. If the concrete type of objPtr is
// a pointer to a pointer to type T (**T), New allocates an object of type
// T and stores a pointer to the object in *objPtr. The object must not
// be accessed after arena a is freed.
func (a *Arena) New(objPtr interface{})
// NewSlice allocates a slice from arena a. If the concrete type of slicePtr
// is *[]T, NewSlice creates a slice of element type T with the specified
// capacity whose backing store is from the arena a and stores it in
// *slicePtr. The length of the slice is set to the capacity. The slice must
// not be accessed after arena a is freed.
func (a *Arena) NewSlice(slicePtr interface{}, cap int)
arena 用法範例:
import (
「arena」
…
)
type T struct {
val int
}
func main() {
a := arena.New()
var ptrT *T
a.New(&ptrT)
ptrT.val = 1
var sliceT []T
a.NewSlice(&sliceT, 100)
sliceT[99] .val = 4
a.Free()
}