【转载】golang内存分配

作者:钱文

Go 的分配采用了类似 tcmalloc 的结构.特点: 使用一小块一小块的连续内存页, 进行分配某个范围大小的内存需求. 比如某个连续 8KB 专门用于分配 17-24 字节,以此减少内存碎片. 线程拥有一定的 cache, 可用于无锁分配.

同时 Go 对于 GC 后回收的内存页, 并不是马上归还给操作系统, 而是会延迟归还, 用于满足未来的内存需求.





在 1.10 以前 go 的堆地址空间是线性连续扩展的, 比如在 1.10(linux amd64)中, 最大可扩展到 512GB. 因为 go 在 gc 的时候会根据拿到的指针地址来判断是否位于 go 的 heap 的, 以及找到其对应的 span, 其判断机制需要 gc heap 是连续的. 但是连续扩展有个问题, cgo 中的代码(尤其是 32 位系统上)可能会占用未来会用于 go heap 的内存. 这样在扩展 go heap 时, mmap 出现不连续的地址, 导致运行时 throw.

在 1.11 中, 改用了稀疏索引的方式来管理整体的内存. 可以超过 512G 内存, 也可以允许内存空间扩展时不连续.在全局的 mheap struct 中有个 arenas 二阶数组, 在 linux amd64 上,一阶只有一个 slot, 二阶有 4M 个 slot, 每个 slot 指向一个 heapArena 结构, 每个 heapArena 结构可以管理 64M 内存, 所以在新的版本中, go 可以管理 4M*64M=256TB 内存, 即目前 64 位机器中 48bit 的寻址总线全部 256TB 内存.





go 的内存分配类似于 tcmalloc, 采用了 span 机制来减少内存碎片. 每个 span 管理 8KB 整数倍的内存, 用于分配一定范围的内存需求.

相关推荐
Hilaku30 分钟前
为什么同一段代码在 Safari 上永远有 Bug?
前端·javascript·程序员
两万五千个小时41 分钟前
DeepSeek Harness 上下文压缩:长对话管理
人工智能·程序员·架构
CodeSheep14 小时前
又一个华为天才少年,离职了!
前端·后端·程序员
AskHarries17 小时前
如何建立关键词库
程序员
老马952717 小时前
把酒言欢
程序员
老马952718 小时前
赴佳期
程序员
Mr_凌宇19 小时前
codex开启1M上下文
人工智能·程序员
编程快车20 小时前
用 Phaser 4 造一个空间解谜游戏:纯函数棋盘引擎、透明画布分层与轻量双语
前端·程序员
Hilaku20 小时前
为什么跳槽涨薪 30% 的时代彻底结束了?聊聊 2026 前端薪资的天花板
前端·javascript·程序员
程序员cxuan21 小时前
本地跑一个 Qwen 3.8,你将拥有一个 Opus 4.6
人工智能·后端·程序员