The Go language community is discussing a new proposal called “arena”.

arena

According to the proposal, “Go arena” is used to optimize memory allocation. arena is a method of allocating a set of memory objects from contiguous memory regions, with the advantage that allocating objects from arena is generally more efficient than general memory allocation. More importantly, objects in arena can be released all at once with minimal memory management or garbage collection overhead.

In general, arena is not implemented in programming languages that have garbage collection because the operations they use to explicitly free arena memory are unsafe and therefore do not conform to garbage collection semantics. However, this proposed implementation uses dynamic checks to ensure that arena operations are safe. It also guarantees that if an arena operation is unsafe, the program will terminate before any incorrect behavior occurs. The Go team has now implemented and used arena internally at Google, and the results show that it saves up to 15% of CPU and memory usage for many large applications, mainly due to reduced garbage collection CPU time and heap memory usage.

Proposal Introduction

Add a new arena package to the Go standard library. The arena package can be used to allocate any number of arena’s, any type of object can be allocated from the arena’s memory, and the arena will automatically grow in size as needed. When all objects in an arena are no longer in use, the arena can be explicitly freed to efficiently reclaim its memory without the need for the usual garbage collection operations. We require this implementation to provide safety checks so that if an arena operation is unsafe, the program will terminate before any incorrect behavior occurs. For maximum flexibility, the API is able to allocate any type of object and slice, including types that can be generated at runtime through reflection.

Proposal API.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 Usage examples.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
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()
}

Click here for details.