当前位置: 首页 > news >正文

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 变量会逃逸到堆上

相关文章:

  • LabVIEW用户界面(UI)和用户体验(UX)设计
  • 如何本地部署DeepSeek
  • HTML之JavaScript运算符
  • macOS部署DeepSeek-r1
  • oracle使用动态sql将多层级组织展平
  • C++自研游戏引擎-碰撞检测组件-八叉树AABB检测算法实现
  • 企业文件安全:零信任架构下的文件访问控制
  • 深度学习|表示学习|Instance Normalization 全面总结|26
  • 网络安全架构师怎么考 网络安全 架构
  • 在Ubuntu中安装Docker并配置国内镜像
  • PHP高效、轻量级表格数据处理库 OpenSpout ,很好用
  • 机器学习 - 词袋模型(Bag of Words)实现文本情感分类的详细示例
  • 开源、免费项目管理工具比较:2025最新整理30款
  • 【系统架构设计师】操作系统 - 进程管理 ② ( 进程状态 | 三态模型 | 五态模型 | 进程状态 划分依据 | PCB 程序控制块 的 组织方式 )
  • 认识一下redis的分布式锁
  • MySQL常见错误码及解决方法(1130、1461、2003、1040、2000、1049、1062、1129、2002、1690等)
  • C#数据库操作系列---SqlSugar完结篇
  • 【Unity Shader编程】之GPU编程前言
  • wordpress主题设置教程
  • 2025年SEO自动优化工具
  • 怎么做弹幕网站/营销网站建设选择原则
  • 传统网站建设/seo分析
  • 网站怎么做一级域名跳转/seo推广优化排名软件
  • 网站服务费怎么做分录/福建seo关键词优化外包
  • 如何用ps设计网页首页/天津seo代理商
  • 电子商务网站建设与管理/营销策划方案怎么写?