go局部变量的存储空间是堆仍是栈?

go局部变量的存储空间是堆仍是栈?

编译器会自动选择在栈上仍是在堆上分配局部变量的存储空间,但可能使人惊讶的是,这个选择并非由用var仍是new声明变量的方式决定的。函数

var global *int

func f() {
    var x int
    x = 1
    global = &x
}

func g() {
    y := new(int)
    *y = 1
}

f函数里的x变量必须在堆上分配,由于它在函数退出后依然能够经过包一级的global变量找到,虽然它是在函数内部定义的;用Go语言的术语说,这个x局部变量从函数f中逃逸了。相反,当g函数返回时,变量y将是不可达的,也就是说能够立刻被回收的。所以,y并无从函数g中逃逸,编译器能够选择在栈上分配*y的存储空间(译注:也能够选择在堆上分配,而后由Go语言的GC回收这个变量的内存空间),虽然这里用的是new方式。其实在任什么时候候,你并不需为了编写正确的代码而要考虑变量的逃逸行为,要记住的是,逃逸的变量须要额外分配内存,同时对性能的优化可能会产生细微的影响。性能

Go语言的自动垃圾收集器对编写正确的代码是一个巨大的帮助,但也并非说你彻底不用考虑内存了。你虽然不须要显式地分配和释放内存,可是要编写高效的程序你依然须要了解变量的生命周期。例如,若是将指向短生命周期对象的指针保存到具备长生命周期的对象中,特别是保存到全局变量时,会阻止对短生命周期对象的垃圾回收(从而可能影响程序的性能)。优化

相关文章
相关标签/搜索