当前位置: 首页 > 科技观察

下面来分析一下Go语言转义_0

时间:2023-03-22 13:07:02 科技观察

1。简介熟悉C/C++的读者应该知道,一个进程(应用程序)的虚拟内存空间分为栈内存区和堆内存区。对象在栈内存区的内存空间是自动分配和销毁的,用户不需要关心。但是堆内存区中对象的内存空间需要用户自己管理,无形中增加了用户的精神负担。因此,一些高级语言支持垃圾回收(GC),以减轻用户内存管理的精神负担。支持垃圾回收的语言可以自动管理堆内存区上对象的内存空间。Go语言编译器负责决定将对象分配在栈上还是堆上。例如,当一个对象在函数退出后不可达时(没有其他对象引用该对象),则将该对象分配到栈上,否则分配到堆上。如果一个对象分配在堆上,则需要Go的垃圾回收来管理对象的内存空间。然而,垃圾收集是有代价的,它会占用系统开销。因此,为了尽量减少垃圾回收占用的系统资源,增加应用程序自身可用的系统资源,用户需要尽量减少堆内存分配,尽可能让应用程序使用栈内存分配,尽可能避免Go编译尽可能。分配到栈内存的对象经过逃逸分析优化后逃逸到堆内存。2.检查物体是否逃逸。Go语言工具链提供了检查对象是否逃逸的方法。我们在执行gobuild时,通过参数-gcflags开启编译器支持的附加功能,例如:gobuild-gcflasg'-m-m-l'main.go-m用于输出编译器的执行细节,包括执行逃逸分析。-l用于禁用内联优化。我们使用Go语言工具链运行一个简单的示例代码来查看对象是否逃逸。funcmain(){sum(1,2)}funcsum(a,bint)*int{res:=a+breturn&res}输出:gobuild-gcflags'-m-m-l'main.go#命令行参数./main.go:8:2:resescapestoheap:./main.go:8:2:flow:~r0=&res:./main.go:8:2:from&res(address-of)at./main.go:9:9./main.go:8:2:fromreturn&res(return)at./main.go:9:2./main.go:8:2:movedtoheap:res阅读上面的代码,我们发现sum函数中的变量res逃逸到了堆中,也就是说Go编译器通过逃逸分析决定将变量res分配到堆空间。3、逃逸分析的作用Go语言编译器通过逃逸分析进行优化,将对象合理分配到栈空间和堆空间。由于栈内存分配比堆内存分配速度快,Go语言在编译时通过逃逸分析优化,对不会逃逸到栈空间的对象进行分配优化。因此,不仅减少了堆空间内存分配的开销,还可以减少垃圾回收占用的系统资源。4.小结本文介绍了Go语言的逃逸分析,可以帮助用户合理分配对象的内存空间。我们知道分配到堆内存空间的对象会导致Go进行垃圾回收,而垃圾回收会占用系统资源,减少应用程序自身可用的系统资源。因此,在实际项目开发中,我们可以使用Go工具链来分析对象是否会逃逸,尽量避免不必要的对象逃逸。