为什么在Go语言中常量会逃逸到堆上?

huangapple go评论71阅读模式
英文:

Why a constant escapes to heap in golang?

问题

这是我用Golang编写的将键C设置为值1的Redis代码。

它使用第三方代码连接到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)
	}
}

在执行go build -gcflags "-m -m"时,报告如下:

./del.go:41: 1逃逸到堆上

./del.go:41: 从c.Do("SET", "C", 1)(间接调用的参数)到./del.go:41

为什么1会逃逸到堆上?它只是一个简单的常量,在编译时完全知道其完整信息,并且在64位系统上只占用64位。为什么它需要存储在堆内存中?

英文:

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?

答案1

得分: 13

Do的签名是:

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

因为args是一个可变参数(interface{}的切片),它在堆上分配内存。

我相信在未来的Go版本中,对于像这样的简单情况可能会有一些优化措施:https://github.com/golang/go/issues/15528

英文:

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

huangapple
  • 本文由 发表于 2017年6月22日 19:20:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/44697906.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定