首页 > 其他 > 详细

逃逸分析

时间:2021-01-04 14:45:11      阅读:18      评论:0      收藏:0      [点我收藏+]

1 编译原理中,分析指针动态范围的方法称之为逃逸分析,Go语言的逃逸分析是编译器执行静态代码分析后,对内存管理进行的优化和简化,它可以决定一个变量是分配到堆还栈上。

go在编译的时候进行逃逸分析,来决定一个对象放栈上还是放堆上,不逃逸的对象放栈上,可能逃逸的放堆上。

编译器会根据变量是否被外部引用来决定是否逃逸:如果在函数外面没有引用到,则优先放到栈区中;如果在函数外面存在引用的可能,则就会放到堆区中;

技术分享图片
//1 将变量取地址返回
//func test() *User{
//    a := User{}
//    return &a
//}

//// 当输入的变量或指针,直接返回时,不会逃逸,
//type S struct {}
//func main() {
//    var x S
//    y := &x
//    _ = fun1(y)
//    _ = fun2(x)
//}
//// 输入直接当成返回值了,因为没有对z作引用,所以z没有逃逸
//func fun1(z *S) *S {
//    return z
//}
//func fun2(k S) S {
//    return k
//}


//// z是对x的拷贝,ref函数中对z取了引用,所以z不能放在栈上,
//// 否则在ref函数之外,通过引用如何找到z,所以z必须要逃逸到堆上
//package main
//type S struct {}
//func main() {
//    var x S
//    _ = *ref(x)
//}
//func ref(z S) *S {
//    return &z
//}


// refStruct函数对y取了引用,所以y发生了逃逸,z没有逃逸,
type S struct {
    M *int
}
func main() {
    var i int
    i = 2
    refStruct(i)
}
// z不会逃逸,因为z是普通变量,返回z的时候是值拷贝,
func refStruct(y int) (z S) {
    z.M = &y
    return z
}
// 这里的z会逃逸,因为返回的是指针,且z是内部开辟的内存,
//func refStruct(y int) (z *S) {
//    z = new(S)
//    z.M = &y
//    return z
//}


// 这里的y没有逃逸,z也没有逃逸,
//type S struct {
//    M *int
//}
//func main() {
//    var i int
//    refStruct(&i)
//}
//func refStruct(y *int) (z S) {
//    z.M = y
//    return z
//}

////3 被指针类型的slice、map和chan引用的指针,注意必须是指针,一定发生逃逸
//func main() {
//    a := make([]*int,1)
//    b := 12
//    a[0] = &b
//
//    c := make(map[string]*int)
//    d := 14
//    c["aaa"]=&d
//
//    e := make(chan *int,1)
//    f := 15
//    e <- &f
//}
View Code

参考:https://mp.weixin.qq.com/s?__biz=Mzg3NDUxNDg4Mw==&mid=100000184&idx=1&sn=1f2ce0d8a9c522b6d9a4a581a76adee1&chksm=4eced11479b95802ea205a569789efca7c59cd6b475ddbe8b2378904da893d0eede0210eb283#rd

 

https://blog.csdn.net/dianfu2892/article/details/101467101

逃逸分析

原文:https://www.cnblogs.com/xxswkl/p/14229446.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!