zoukankan      html  css  js  c++  java
  • Go

    前言

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

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

    什么是逃逸分析?

    在编译程序优化理论中,逃逸分析是一种确定指针动态范围的方法,简单来说就是分析在程序的哪些地方可以访问到该指针。

    简单的说,它是在对变量放到堆上还是栈上进行分析,该分析在编译阶段完成。如果一个变量超过了函数调用的生命周期,也就是这个变量在函数外部存在引用,编译器会把这个变量分配到堆上,这时我们就说这个变量发生逃逸了。

    如何确定是否逃逸?

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

    可能出现逃逸的场景

    01

    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
    

    02

    package main
    
    type Student struct {
    	Name string
    }
    
    func GetStudent() *Student {
    	stu := new(Student)
    	stu.Name = "tom"
    	return stu
    }
    
    func main() {
    	GetStudent()
    }
    
    

    分析结果:

    go run -gcflags '-m -l' 02.go
    # command-line-arguments
    ./02.go:8:12: new(Student) escapes to heap
    

    返回指针类型,会发生逃逸,优化方案视情况而定。

    函数传递指针和传值哪个效率高吗?我们知道传递指针可以减少底层值的拷贝,可以提高效率,但是如果拷贝的数据量小,由于指针传递会产生逃逸,可能会使用堆,也可能会增加 GC 的负担,所以传递指针不一定是高效的。

    不要盲目使用变量指针作为参数,虽然减少了复制,但变量逃逸的开销可能更大。

    03

    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
    

    栈空间不足,会发生逃逸,优化方案尽量设置容量,如果容量实在过大那就没办法了。

    小结

    1. 逃逸分析是编译器在静态编译时完成的。
    2. 逃逸分析后可以确定哪些变量可以分配在栈上,栈的性能好。

    以上,希望对你能够有所帮助。

    推荐阅读

    作者:新亮笔记(关注公众号,可申请添加微信好友)
    出处:https://www.cnblogs.com/xinliangcoder
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    怎么让Windows10取消开机登录密码自动登录
    window查看无线网卡bssid以及相关信息命令
    kali-cdlinux-wifi-pj-nanke-心得
    html里文本保留换行格式
    window实用快捷键-ctrl篇
    mybatis 结果映射 collection oftype为string,integer等类型
    Redis集群下只有db0,不支持多db
    软件开发过程中所使用的生命周期模型比较
    简单Dos命令
    简单理解Mysql json数据类型
  • 原文地址:https://www.cnblogs.com/xinliangcoder/p/15485300.html
Copyright © 2011-2022 走看看