Go 语言里中的堆与栈

在 Go 语言里,堆和栈是内存管理的两个重要概念,它们在多个方面存在明显差异:

1. 内存分配与回收方式

    • 分配:Go 语言中,栈内存主要用于存储函数的局部变量和调用信息。当一个函数被调用时,Go 会自动为其在栈上分配一块内存空间,用于存放该函数的局部变量,这个过程由编译器和运行时系统自动完成,速度非常快。
    • 回收:当函数执行完毕返回时,栈上分配的内存会自动被回收,无需程序员手动干预。这种自动回收机制基于栈的后进先出(LIFO)特性,确保了内存的高效管理。
    • 分配 :堆内存用于存储那些在函数调用结束后仍然需要存在的数据,比如通过 new 关键字或 make 函数创建的对象。当需要在堆上分配内存时,Go 的运行时系统会进行一系列操作,包括查找合适的内存块、进行内存对齐等,因此分配过程相对复杂,速度较慢。
    • 回收:堆内存的回收由 Go 的垃圾回收器(GC)负责。垃圾回收器会定期扫描堆内存,标记那些不再被引用的对象,然后将其占用的内存回收。垃圾回收的过程会消耗一定的系统资源,并且可能会导致程序出现短暂的停顿。

2. 数据存储特性

    • 存储内容:主要存储函数的局部变量、函数调用的上下文信息(如返回地址、调用者的栈指针等)。这些变量的生命周期通常与函数的执行周期相同,函数结束时,这些变量就会被销毁。
    • 数据访问:栈上的数据访问速度快,因为栈是一块连续的内存区域,并且其操作遵循后进先出的原则,使得数据的定位和访问非常高效。
    • 存储内容 :存储那些需要在多个函数之间共享的数据,或者生命周期较长的数据。例如,通过 make 函数创建的切片、映射和通道等对象通常存储在堆上。
    • 数据访问:堆上的数据访问相对较慢,因为需要通过指针来间接访问,而且堆内存的布局可能比较分散,不连续。

3. 内存空间大小和限制

    • 每个 Goroutine 都有自己独立的栈空间,栈空间的初始大小是固定的,并且在运行过程中可以动态增长或收缩。不过,栈空间的大小是有限制的,如果栈空间使用超过了限制,会导致栈溢出错误(Stack Overflow)。
    • 堆内存的大小通常受限于系统的物理内存和虚拟内存空间。只要系统还有可用的内存,就可以在堆上分配新的对象。但如果堆内存使用过度,会导致系统性能下降,甚至出现内存不足的错误。

4. 数据逃逸分析

在 Go 语言中,编译器会进行逃逸分析,来决定一个变量是分配在栈上还是堆上。

  • 如果一个变量的生命周期只在函数内部,并且不会被外部引用,那么它通常会被分配到栈上。
  • 如果一个变量的生命周期超出了函数的范围,或者会被外部引用,那么它会逃逸到堆上。逃逸分析有助于优化内存使用,减少垃圾回收的压力。

示例代码说明

复制代码
package main

func stackVariable() {
    // 这个变量会分配在栈上,因为它的生命周期只在函数内部
    num := 10
    println(num)
}

func heapVariable() *int {
    // 这个变量会逃逸到堆上,因为它的指针被返回,生命周期超出了函数范围
    num := new(int)
    *num = 20
    return num
}

func main() {
    stackVariable()
    result := heapVariable()
    println(*result)
}

在上述代码中,stackVariable 函数中的 num 变量会分配在栈上,而 heapVariable 函数中通过 new 创建的 num 变量会逃逸到堆上

相关推荐
不思念一个荒废的名字1 分钟前
【刷题Day29】Python/JAVA - 03(浅)
java·开发语言·jvm·python
CoovallyAIHub2 分钟前
复杂背景下无人机影像小目标检测:MPE-YOLO抗遮挡与抗背景干扰设计
算法·计算机视觉·无人机
成工小白3 分钟前
【Linux】进程状态
linux·算法
Mr.Winter`10 分钟前
无人船 | 图解基于LQR控制的路径跟踪算法(以全驱动无人艇WAMV为例)
人工智能·算法·机器人·ros·ros2·运动规划·无人船
Wneosy12 分钟前
【CodeSprint】第二章-2.1 简单模拟
算法
小小年纪不学好18 分钟前
【60.组合总和】
java·算法·面试
关于不上作者榜就原神启动那件事18 分钟前
力扣hot100,739每日温度(单调栈)详解
算法·leetcode·职场和发展
Miku1619 分钟前
基于SpringAI实现简易聊天对话
java·ai编程
小卡皮巴拉20 分钟前
【力扣刷题实战】丢失的数字
c++·算法·leetcode·位运算
24k小善25 分钟前
FlinkJobmanager深度解析
java·大数据·flink·云计算