go的逃逸分析机制

简介: 快速学习go的逃逸分析机制

什么是逃逸分析

逃逸分析就是分析一个变量是否被引用,然后决定一个变量是分配在一个栈上还是一个堆上


什么是栈和堆

在计算机系统中,栈和堆都是操作系统对内存管理的两种方式。

栈的内存分配速度很快,而且会自动被释放,效率很高。

但是堆的分配速度比较慢,它需要先找到一块内存空间,而且不可以自动释放资源,在go中回收是由垃圾回收机制完成的。


优缺点分析

不管如何栈和堆对于一个程序来说都是储存变量的一个空间。

栈的优点,它是硬件支持的,入栈出栈很快,效率高。那么它就是和储存一些过期时间短、作用域小的变量,比如局部变量。

而堆呢,它的分配速度很慢,就可以储存一些过期时间长、作用域大的变量,比如全局变量。


go的逃逸机制

那么go的逃逸机制设计就是由一个点决定的---就是一个变量是否会被外部引用。

  • 如果变量在函数外部没用被引用,那么他就会优先被分配在栈上
  • 如果变量在函数外部被引用了,那么它就会一定被放到堆上
  • 如果栈上放不下,就一定放在堆上


go常见的内存逃逸场景

  • 返回局部变量指针,因为指针的原因,对象的内存不会随着函数的结束而被回收
  • 栈空间不足,比如创建了一个超长的切片
  • 动态类型逃逸,创建的时候数据类型使用了interface{},编译期间很难确定使用的类型,也会发生逃逸
  • 闭包引用导致逃逸分析
func getSum()func ()int{
    a := 1
    return func()int{
        a++
        return a
    }
}
复制代码


传值真的比传指针效率高吗?

如果拷贝的数据量小,指针可能会发生逃逸,会使用堆,增加GC的负担。所以指针传递效率不一定是最高的


go和c/c++的栈堆概念

  • 在c/c++中栈和堆都是操作系统层级上的概念,是关联硬件的,是由操作系统和编译器共同决定的
  • go中的栈和堆却都是逻辑上的概念(类似数据结构)。操作系统层级上的栈都被调度器、垃圾回收、系统调用等机制消耗了。而我们代码中使用的栈和堆其实是从操作系统申请的一块堆内存模拟出来的,是一种逻辑上的概念。
  • 也因此,c/c++的栈很小。而go的'栈'可以开很大,比如go的一个协程就是一个栈,通常是2或4kb,但可以开成千上万个协程。
  • 而且go有时候为了防止内存碎片化,会对整个栈就行内存迁移,然后拷贝数据(切片扩容机制,当容量大于原数组容量,就会进行迁移拷贝)。所以指针有时候是会变的,只有指针指向的值有意义。因此,go禁止指针的算术运算
相关文章
|
27天前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
74 4
|
27天前
|
存储 安全 Go
Go 语言以其高效的并发编程能力著称,主要依赖于 goroutines 和 channels 两大核心机制
Go 语言以其高效的并发编程能力著称,主要依赖于 goroutines 和 channels 两大核心机制。本文介绍了这两者的概念、用法及如何结合使用,实现任务的高效并发执行与数据的安全传递,强调了并发编程中的注意事项,旨在帮助开发者更好地掌握 Go 语言的并发编程技巧。
33 2
|
27天前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
70 1
|
1月前
|
安全 Go 开发者
代码之美:Go语言并发编程的优雅实现与案例分析
【10月更文挑战第28天】Go语言自2009年发布以来,凭借简洁的语法、高效的性能和原生的并发支持,赢得了众多开发者的青睐。本文通过两个案例,分别展示了如何使用goroutine和channel实现并发下载网页和构建并发Web服务器,深入探讨了Go语言并发编程的优雅实现。
37 2
|
1月前
|
存储 算法 Java
Go语言的内存管理机制
【10月更文挑战第25天】Go语言的内存管理机制
31 2
|
2月前
|
算法 Java 编译器
你为什么不应该过度关注go语言的逃逸分析
【10月更文挑战第21天】逃逸分析是 Go 语言编译器的一项功能,用于确定变量的内存分配位置。变量在栈上分配时,函数返回后内存自动回收;在堆上分配时,则需垃圾回收管理。编译器会根据变量的使用情况自动进行逃逸分析。然而,过度关注逃逸分析可能导致开发效率降低、代码复杂度增加,并且对性能的影响相对较小。编译器优化通常比人工干预更准确,因此开发者应更多关注业务逻辑和整体性能优化。
|
2月前
|
算法 安全 Go
Python与Go语言中的哈希算法实现及对比分析
Python与Go语言中的哈希算法实现及对比分析
46 0
|
2月前
|
机器学习/深度学习 自然语言处理 Go
Python与Go在AIGC领域的应用:比较与分析
Python与Go在AIGC领域的应用:比较与分析
61 0
|
4月前
|
编译器 Go
Go中init()执行顺序分析
文章分析了Go语言中`init()`函数的执行顺序和时机,指出全局变量初始化后先于`init()`函数执行,而`init()`函数在`main()`函数之前执行,且包的`init()`函数按包的导入顺序进行初始化。
35 1
|
4月前
|
存储 编译器 Go