Golang 逃逸分析

逃逸分析是用于确定变量内存分配位置的技术,有助于减少垃圾回收压力,提升程序性能。通过分析,不逃逸的对象可分配在栈上,逃逸的则在堆上。同步消除和栈上分配都是其应用。Go语言通过逃逸分析自动决定对象存储位置。开启逃逸分析日志可观察编译结果。示例展示了如何通过调整类型避免逃逸。
摘要由CSDN通过智能技术生成

为什么需要了解逃逸分析?

因为我们想要提升程序性能,通过逃逸分析我们能够知道变量是分配到堆上还是栈上,如果分配到栈上,内存的分配和释放都是由编译器进行管理,分配和释放的速度非常快,如果分配到堆上,堆不像栈那样可以自动清理,它会引起频繁地进行垃圾回收(GC),而垃圾回收会占用比较大的系统开销。

什么是逃逸分析?

逃逸分析是一种确定指针动态范围的方法,可以分析在程序的哪些地方可以访问到指针。它涉及到指针分析和形状分析。 当一个变量(或对象)在子程序中被分配时,一个指向变量的指针可能逃逸到其它执行线程中,或者去调用子程序。如果使用尾递归优化(通常在函数编程语言中是需要的),对象也可能逃逸到被调用的子程序中。 如果一个子程序分配一个对象并返回一个该对象的指针,该对象可能在程序中的任何一个地方被访问到——这样指针就成功“逃逸”了。如果指针存储在全局变量或者其它数据结构中,它们也可能发生逃逸,这种情况是当前程序中的指针逃逸。 逃逸分析需要确定指针所有可以存储的地方,保证指针的生命周期只在当前进程或线程中。

逃逸分析的用处

最大的好处应该是减少gc的压力,不逃逸的对象分配在栈上,当函数返回时就回收了资源,不需要gc标记清除。
因为逃逸分析完后可以确定哪些变量可以分配在栈上,栈的分配比堆快,性能好。
同步消除,如果你定义的对象的方法上有同步锁,但在运行时,却只有一个线程在访问,此时逃逸分析后的机器码,会去掉同步锁运行。

go消除了堆和栈的区别
go在一定程度消除了堆和栈的区别,因为go在编译的时候进行逃逸分析,来决定一个对象放栈上还是放堆上,不逃逸的对象放栈上,可能逃逸的放堆上。

开启逃逸分析日志

编译参数加入 -gcflags ‘-m -l’

例如:

go run -gcflags '-m -l' main.go

场景示例一

package main

type Student struct {
    Name interface{}
}

func main()  {
    stu := new(Student)
    stu.Name = "tom"

}

分析结果:

go run -gcflags '-m -l' 01.go
# command-line-arguments
./01.go:8:12: new(Student) does not escape
./01.go:9:11: "tom" escapes to heap

interface{} 赋值,会发生逃逸,优化方案是将类型设置为固定类型,例如:string

package main

type Student struct {
    Name string
}

func main()  {
    stu := new(Student)
    stu.Name = "tom"

}

分析结果:

go run -gcflags '-m -l' 01.go
# command-line-arguments
./01.go:8:12: new(Student) does not escape

场景示例二

package main

func main() {
    nums := make([]int, 10000, 10000)

    for i := range nums {
        nums[i] = i
    }
}

分析结果:

go run -gcflags '-m -l' 03.go
# command-line-arguments
./03.go:4:14: make([]int, 10000, 10000) escapes to heap
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kuokay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值