【转载】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 整数倍的内存, 用于分配一定范围的内存需求.

相关推荐
马可奥勒留9 小时前
世界之大,无奇不有
程序员
一只爱撸猫的程序猿15 小时前
防止外部API服务不可用拖垮系统的解决方案
spring boot·后端·程序员
货拉拉技术15 小时前
LLM 驱动前端创新:AI 赋能营销合规实践
前端·程序员·llm
冰 河16 小时前
《Mycat核心技术》第21章:高可用负载均衡集群的实现(HAProxy + Keepalived + Mycat)
分布式·微服务·程序员·分布式数据库·mycat
陈哥聊测试16 小时前
国产化替代是个伪命题?被误解多年的开源软件,如今怎么样了?
程序员·开源·产品
欧达克20 小时前
AI 嘴替,社交平台反杠机器人:第 2 篇-AI 助手
程序员
观默1 天前
AI 时代的 10 倍速学习指南
人工智能·程序员
灵感__idea1 天前
JavaScript高级程序设计(第5版):扎实的基本功是唯一捷径
前端·javascript·程序员
炼数成金2 天前
程序员副业暴利指南:用Python+AI在小红书月入1W+的终极玩法
人工智能·程序员
444A4E2 天前
C++ STL容器适配器深度剖析:从deque原理到stack/queue的底层实现
程序员