go的协程栈

        golang的堆栈跟C++的堆栈是有所不同的,golang的栈是在堆上的,而C++的堆栈是分开的,golang协程栈的作用是记录协程的执行路径,局部变量,函数传参和函数返回值。简单的步骤如下:

 

 

         另外,go的协程栈初始空间还是比较小的,只有2k到4k,那么当我们遇到局部变量太大,栈帧太多的时候,栈空间不够用了怎么办呢??

        这里就涉及到逃逸分析了。

        不是所有的变量都能放在协程栈上的。栈帧回收时,需要继续使用的变量这时就会逃逸到堆上去。然后变量太大也会逃逸到堆上去。

        逃逸也分指针逃逸,空接口逃逸和大变量逃逸。

        指针逃逸也很容易判断,比如下列函数,返回的是个指针,因为返回值在其他的函数还会用到,所以这时会逃逸到堆上。        

         空接口逃逸:如果函数参数为interface{},那么函数的实参很可能会逃逸,这个有点难分析,比如下列代码,你会以为i是实打实的局部变量,只在b函数里面使用,并不会逃逸,那么就错了。为什么?因为我们调用了Println函数,我们来看看Println的源代码,他的接收参数是空接口类型,那么就很有可能会逃逸,因为interface{}类型的函数往往会使用反射来看一下我传的值是什么类型的,用到反射就往往会逃逸到堆上了,因为在栈上很难做反射。

 

         大变量逃逸:过大的变量会导致栈空间不足,那就会让他逃逸到堆上。在64位机器中,一般超过64KB的变量会逃逸。

        通过逃逸我们能够解决大变量,那么栈帧太多怎么办呢?其实也没啥好办法,也就是栈扩容。在函数调用前会判断栈空间是否足够,如果不足够呢就会进行栈扩容,1.13之前使用的是分段栈方法,之后用的连续栈方法。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值