近日,Go 语言社区正在探讨名为「arena」的新提案。

据介绍,arena 是一种从间断的内存区域调配一组内存对象的办法,其长处是从 arena 调配对象通常比个别内存调配更无效,更重要的是,arena 中的对象能够以起码的内存治理或垃圾回收开销一次开释所有内容。

arena 通常不会在具备垃圾回收的编程语言中实现,因为它们用于显式开释 arena 内存的操作并不平安,所以不合乎垃圾回收语义。

然而,此提案的实现应用了动静查看来确保 arena 操作是平安的。如果 arena 操作不平安,程序将在任何不正确的行为产生之前终止。

目前 Go 团队已在Google 外部应用了arena,结果显示 arena为许多大型应用程序节俭了高达 15% 的 CPU 和内存使用量,这次要是因为垃圾回收CPU 工夫和堆内存使用量的缩小。

提案介绍

Go 团队试图在Go 规范库中增加一个新的 arena 包。arena 包将调配任意数量的 arena,能够从 arena 的内存中调配任意类型的对象,并且 arena 会依据须要主动增长大小。

当一个 arena 中的所有对象不再应用时,能够显式开释该 arena 以无效地回收其内存,而无需进行个别的垃圾回收操作。Go 团队要求此实现提供安全检查,如果 arena操作不平安,程序将在任何不正确的行为产生之前终止。为了取得最大的灵活性,API 可能调配任何类型的对象和切片,包含能够在运行时通过反射生成的类型。

提案 API

package arenatype 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)

用法示例:

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()}