Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why a constant escapes to heap in golang?

Here is my golang code to set a key C to value 1 in redis

It uses third party code in order to connect to redis.

package main

import (
    "github.com/garyburd/redigo/redis"
)

func main() {

    c, err := redis.Dial("tcp", ":6379")

    _, err = c.Do("SET", "C", 1)
    if err != nil {
        panic(err)
    }
}

On doing go build -gcflags "-m -m", it reports

./del.go:41: 1 escapes to heap

./del.go:41: from c.Do("SET", "C", 1) (parameter to indirect call) at ./del.go:41

Why does 1 escape to the heap ? It is a simple constant whose complete information is known at compile time and it takes just 64bits on a 64bit system. Why should it be stored in heap memory?

like image 681
user3219492 Avatar asked Jun 22 '17 11:06

user3219492


People also ask

What is Escape analysis in Golang?

It analyses the source code and determines what variables should be allocated on the stack and which ones should escape to the heap. To see this analysis, use the flag -gcflags="-m" while running go run or go build. Here is a simple example: Running the escape analysis shows us tmp escapes to the heap: But why.

What goes on heap vs stack?

Heap memory is used by all the parts of the application whereas stack memory is used only by one thread of execution. Whenever an object is created, it's always stored in the Heap space and stack memory contains the reference to it.

How do I allocate memory dynamically in Golang?

In Go dynamic memory block is allocated mainly using new and make. New allocates exact one memory block that is used to create struct type value, whereas, make creates more than one memory block and returns the reference, like a slice, map or channel value.

Does Golang have a heap?

All goroutines share a common heap and anything that can't be stored on the stack will end up there. When a heap allocation occurs in a function being benchmarked, we'll see the allocs/ops stat go up by one. It's the job of the garbage collector to later free heap variables that are no longer referenced.


1 Answers

The signature of Do is:

Do(commandName string, args ...interface{}) (reply interface{}, err error)

Because args is a variadic (slice of) interface{} it's heap allocated.

I believe there could be some optimisations in the pipeline for simple cases like this in future versions of Go: https://github.com/golang/go/issues/15528

like image 81
Martin Gallagher Avatar answered Sep 21 '22 14:09

Martin Gallagher