GO内存管理

内存管理

内存管理

go 复制代码
xxx

内存分配

go 复制代码
内存分配有两种方式:栈分配和堆分配

- 栈分配是在函数调用时为局部变量分配内存,当函数返回时,这些内存会自动释放
- 堆分配则是通过 new 或者 make 函数动态分配内存,需要GC释放

编译器会自动选择在栈上还是在堆上,来分配局部变量的存储空间
如果一个局部变量在函数返回后仍然被使用,这个变量会从heap,而不是stack中分配内存

内存逃逸

go 复制代码
原本应该在栈上分配的内存被分配到了堆上
  • 场景
go 复制代码
- 变量的生命周期超出了其作用域
- 大对象的分配
- 闭包引用
- 在 interface 类型上调用方法
- 在 slice 或 map 中存储指针
  • 检测
go 复制代码
go build -gcflags -m main.go 
  • 优化策略
go 复制代码
- 严格限制变量的作用域
- 对于小型的数据,使用传值而不是传指针
- 避免使用长度不固定的slice切片

内存泄漏

go 复制代码
// 在程序执行过程中,已不再使用的内存空间没有被及时释放或者释放时出现了错误
// 导致这些内存无法被使用,直到程序结束这些内存才被释放。
  • 分类
go 复制代码
// 分为暂时性内存泄漏和永久性内存泄漏
- 暂时性内存泄漏
	- 获取长字符串中的一段导致长字符串未释放
	- 获取长slice中的一段导致长slice未释放
	- defer 导致的内存泄漏
- 永久性内存泄漏
	- goroutine 泄漏导致内存泄漏
	- 定时器使用不当,time.Ticker未关闭导致内存泄漏
	- 不正确地使用终结器(Finalizers)导致内存泄漏
goroutine泄漏导致内存泄漏
  • 本质
go 复制代码
goroutine 阻塞,无法继续向下执行,导致此 goroutine 关联的内存都无法释放,进一步造成内存泄漏
  • 两种方式造成内存泄漏:
go 复制代码
1. goroutine本身的栈所占用的空间造成内存泄漏
2. goroutine中的变量所占用的堆内存导致堆内存泄漏
  • 泄漏的场景
go 复制代码
- channel 阻塞
- select 操作
- 互斥锁没有释放,互斥锁死锁
- 申请过多的goroutine来不及释放
  • 发现和定位
go 复制代码
1.go pprof获取goroutine profile文件
2.top、traces、list定位内存泄漏的原因
判断依据:
	在节点正常运行的情况下,隔一段时间获取goroutine的数量
	- 如果后面获取的那次,某些goroutine比前一次多,
	- 如果多获取几次,是持续增长的
	- 就极有可能是goroutine泄漏
  • 在 goroutine 里调用的一些资源,没有 close
  • 在 goroutine 操作 channel,因一些原因被阻塞
  • select操作在所有case上都阻塞,造成内存泄漏
不正当使用内存场景
  • 大数组作为参数导致短期内内存激增
  • goroutine阻塞拥挤等待,浪费内存
相关推荐
鹏北海-RemHusband9 小时前
Go 语言进阶笔记 — 面向 JS/TS 前端开发者
笔记·golang
atomicmaker16 小时前
操作系统 — 内存管理
操作系统·内存管理·虚拟内存·段页式
Starry-sky(jing)18 小时前
Hermes Agent 接入 Qwen3.7-Max 报 401?OpenCode Go 模型路由源码级排查与修复
开发语言·人工智能·chrome·golang
鹏北海-RemHusband18 小时前
Go 语言基础笔记 — 面向 JS/TS 前端开发者
笔记·golang
鹏北海-RemHusband21 小时前
Go 包管理笔记 — 面向 JS/TS 前端开发者
笔记·golang
jieyucx21 小时前
Go 语言 JSON 序列化/反序列化:Tag 用法完全指南
开发语言·golang·json·序列化·tag
前网易架构师-高司机21 小时前
ROS2 Jazzy+Gazebo Harmonic 环境下,用 URDF 搭建机器人,配置物理属性、插件与桥接,修复车轮和激光雷达故障 (手把手保姆级教程)
开发语言·算法·golang·机器人·ros
Reisentyan21 小时前
[Review]GoLang Learn Data Day 3
java·开发语言·golang
止语Lab1 天前
从文件到配置中心:Go 配置管理的三个升级拐点
开发语言·后端·golang
Tony Bai1 天前
从 Go 迁移到 Rust
开发语言·后端·golang·rust