Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang. Zero Garbage propagation or efficient use of memory

From time to time I face with the concepts like zero garbage or efficient use of memory etc. As an example in the section Features of well-known package httprouter you can see the following:

Zero Garbage: The matching and dispatching process generates zero bytes of garbage. In fact, the only heap allocations that are made, is by building the slice of the key-value pairs for path parameters. If the request path contains no parameters, not a single heap allocation is necessary.

Also this package shows very good benchmark results compared to standard library's http.ServeMux:

BenchmarkHttpServeMux         5000     706222 ns/op          96 B/op        6 allocs/op
BenchmarkHttpRouter         100000      15010 ns/op           0 B/op        0 allocs/op

As far as I understand the second one has (from the table) no heap memory allocation and zero average number of allocations made per repetition.

The question: I want to learn a basic understanding of memory management. When garbage collector allocates/deallocates memory. What does the benchmark numbers means (the last two columns of the table) and how people know when heap is allocating?

I'm absolutely new in memory management, so it's really difficult to understand what's going on "under the hood". The articles I've read:

  • https://golang.org/ref/mem
  • https://golang.org/doc/effective_go.html
  • http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html
  • http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
like image 716
Timur Fayzrakhmanov Avatar asked Feb 28 '15 10:02

Timur Fayzrakhmanov


People also ask

How does Golang allocate memory?

Go uses OS function mmap similar to TCMalloc (Thread-Caching Malloc) to allocate memory in heap. Go uses goroutine, which maintain a small stack (memory segment) act as memory pool for some memory blocks. The maximum stack size is 1 GB on 64-bit systems, and 250 MB on 32-bit systems, can be set by SetMaxStack function.

Does Golang do garbage collection?

Go has all goroutines reach a garbage collection safe point with a process called stop the world. This temporarily stops the program from running and turns a write barrier on to maintain data integrity on the heap. This allows for concurrency by allowing goroutines and the collector to run simultaneously.

Does Go use stack or heap?

Go prefers allocation on the stack — most of the allocations within a given Go program will be on the stack. It's cheap because it only requires two CPU instructions: one to push onto the stack for allocation, and another to release from the stack. Unfortunately not all data can use memory allocated on the stack.

Does Go have a heap?

The Go heap is again conceptually similar to the threaded model described above. All goroutines share a common heap and anything that can't be stored on the stack will end up there.


1 Answers

The garbage collector doesn't allocate memory :-), it just deallocates. Go's garbage collector is evolving, for the details have a look at the design document https://docs.google.com/document/d/16Y4IsnNRCN43Mx0NZc5YXZLovrHvvLhK_h0KN8woTO4/preview?sle=true and follow the discussion on the golang mailing lists.

The last two columns in the benchmark output are dead simple: How many bytes have been allocated in total and how many allocations have happened during one iteration of the benchmark code. (This allocation is done by your code, not by the garbage collector). As any allocation is a potential creation of garbage reducing these numbers might be a design goal.

When are things allocated on the heap? Whenever the Go compiler decides to! The compiler tries to allocate on the stack, but sometimes it must use the heap, especially if a value escapes from the local stack-bases scopes. This escape analysis is currently undergoing rework, so it is not easy to tell which value will be heap- or stack-allocated, especially as this is changing from compiler version to version.

I wouldn't be too obsessed with avoiding allocations until your benchmarking show too much GC overhead.

like image 169
Volker Avatar answered Oct 20 '22 10:10

Volker