Golang内存模型

gc

遍历看有没有引用该变量地址的地方,没有的话就回收。

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

 

局部变量

如果外部没有引用,则在栈上分配空间;如果外部变量引用了局部变量,则称为局部变量逃逸,并只能在堆上分配空间。

栈上空间不用gc回收,函数运行完后,栈上空间立马消失

 

全局变量

在堆上,因为函数结束后,全局变量依然可以访问

 

例 (摘自:gopl 2.3.4函数的声明周期)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值