逃逸分析

逃逸分析的好处:

1 逃逸分析的好处是为了减少gc的压力,不逃逸的对象分配在栈上,当函数返回时就回收了资源,不需要gc标记清除。

2 逃逸分析完后可以确定哪些变量可以分配在栈上,栈的分配比堆快,性能好(逃逸的局部变量会在堆上分配 ,而没有发生逃逸的则有编译器在栈上分配)。

3 同步消除,如果你定义的对象的方法上有同步锁,但在运行时,却只有一个线程在访问,此时逃逸分析后的机器码,会去掉同步锁运行。

四种情况会逃逸:1 函数内new后,返回指针  2 空间不足,如用make函数申请的空间过大,会分配到堆上,3 类型不确定 a 赋值给接口类型,b make申请的空间大小不确定,  4 闭包内的变量,

参考:https://driverzhang.github.io/post/golang%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E9%80%83%E9%80%B8%E5%88%86%E6%9E%90/

 

 

 

 

 

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

posted on 2021-01-04 13:58  吃我一枪  阅读(273)  评论(0编辑  收藏  举报

导航