Go最新golang_逃逸分析_golang escapes to heap,阿里后台开发

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!


函数StudentRegister()内部s为局部变量,其值通过函数返回值返回,s本身为一指针,其指向的内存地址不会是栈而是堆,这就是典型的逃逸案例。


### 2.栈空间不足



package main

func Slice() {
s := make([]int, 1000, 1000)

for index, \_ := range s {
    s[index] = index
}

}

func main() {
Slice()
}



> 
> 上面代码Slice()函数中分配了一个1000个长度的切片,是否逃逸取决于栈空间是否足够大。 直接查看编译提示,如下:
> 
> 
> 



D:\SourceCode\GoExpert\src>go build -gcflags=-m

_/D_/SourceCode/GoExpert/src

.\main.go:4: Slice make([]int, 1000, 1000) does not escape



> 
> 我们发现此处并没有发生逃逸。那么把切片长度扩大10倍即10000会如何呢?
> 
> 
> 



D:\SourceCode\GoExpert\src>go build -gcflags=-m

_/D_/SourceCode/GoExpert/src

.\main.go:4: make([]int, 10000, 10000) escapes to heap


我们发现当切片长度扩大到10000时就会逃逸。  
 实际上当栈空间不足以存放当前对象时或无法判断当前切片长度时会将对象分配到堆中。


### 3.动态类型逃逸



> 
> 很多函数参数为interface类型,比如fmt.Println(a …interface{}),编译期间很难确定其参数的具体类型,也会产生逃逸。 如下代码所示:
> 
> 
> 



package main

import “fmt”

func main() {
s := “Escape”
fmt.Println(s)
}



> 
> 上述代码s变量只是一个string类型变量,调用fmt.Println()时会产生逃逸:
> 
> 
> 



D:\SourceCode\GoExpert\src>go build -gcflags=-m

_/D_/SourceCode/GoExpert/src

.\main.go:7: s escapes to heap
.\main.go:7: main … argument does not escape


### 4.闭包引用对象逃逸



func Fibonacci() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return a
}
}



> 
> 该函数返回一个闭包,闭包引用了函数的局部变量a和b,使用时通过该函数获取该闭包,然后每次执行闭包都会依次输出Fibonacci数列。 完整的示例程序如下所示:
> 
> 
> 



package main

import “fmt”

func Fibonacci() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return a
}
}

func main() {
f := Fibonacci()

for i := 0; i < 10; i++ {
    fmt.Printf("Fibonacci: %d\n", f())
}

}



> 
> 上述代码通过Fibonacci()获取一个闭包,每次执行闭包就会打印一个Fibonacci数值。输出如下所示:
> 
> 
> 



D:\SourceCode\GoExpert\src>src.exe
Fibonacci: 1
Fibonacci: 1
Fibonacci: 2
Fibonacci: 3
Fibonacci: 5
Fibonacci: 8
Fibonacci: 13
Fibonacci: 21
Fibonacci: 34
Fibonacci: 55



> 
> Fibonacci()函数中原本属于局部变量的a和b由于闭包的引用,不得不将二者放到堆上,以致产生逃逸:
> 
> 
> 



D:\SourceCode\GoExpert\src>go build -gcflags=-m

_/D_/SourceCode/GoExpert/src

.\main.go:7: can inline Fibonacci.func1
.\main.go:7: func literal escapes to heap
.\main.go:7: func literal escapes to heap
.\main.go:8: &a escapes to heap

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值