本文基于Go1.13

当不再使用内存时,标准库会自动执行Go的内存管理即从分配到回收。尽管开发者不需要处理它,但是Go的底层管理进行了很好的优化并且充满了有趣的概念。

堆上的分配

内存管理被设计可以在并发环境快速执行并且集成了gc。让我们从一个例子开始:

package maintype smallStruct struct {a, b int64c, d float64
}func main() {smallAllocation()
}//go:noinline
func smallAllocation() *smallStruct {return &smallStruct{}
}

注释//go:noinline 将会阻止内联优化,以避免内联通过移除函数的方式优化这段代码,从而造成最终没有分配内存的情况。

运行逃逸分析命令go tool compile "-m" main.go可以确认Go执行了分配:

main.go:14:9: &smallStruct literal escapes to heap

借助go tool compile -S main.go 输出的程序汇编代码,同样可以明确的展示了分配:

0x001d 00029 (main.go:14)   LEAQ   type."".smallStruct(SB), AX
0x0024 00036 (main.go:14)  PCDATA $0, $0
0x0024 00036 (main.go:14)  MOVQ   AX, (SP)
0x0028 00040 (main.go:14)  CALL   runtime.newobject(SB)

函数newobject是新分配对象和代理mallocgc的内置函数,该函数在堆上管理它们。Go中有两种策略,一种用于较小的分配,一种用于较大的分配。

小分配

对于低于32kb的小分配,Go将会尝试从本地mcache 缓存中获取内存。此缓存包含一组mspan

每个M 被分配给一个处理器P并且一次只能处理一个goroutine。当需要分配内存时,当前goroutine会使用它当前P的本地缓存来从中寻找第一个可用空闲对象。使用本地缓存不需要加锁会使得分配更加高效。

mspan被分为约70个尺寸类型,从8字节到32k字节。

每个mspan会存在2次:一个不包含指针,一个包含指针。这种区别会使得gc更加容易因为它不需要扫描那些不包含指针的mspan。

在我们之前的例子里,结构体是32字节所以它适合于32 字节的mspan。

现在会疑惑如果mspan在内存分配时候没有空闲插槽会发生什么。Go维护了包含全尺寸类型的中央链表mcentral,其中包含空闲和非空闲对象的mspan:

mcentral 维护着mspan的双向链表; 在非空链表(non-empty list:尚有空闲object的mspan链表) — 非空(“non-empty” )代表链表中至少有一个插槽是空闲可供分配 — 可能包含一些正在使用的内存。当gc 清理内存时,他会清理一部分mspan标记不再使用,并放回非空链表(non-empty list)

我们程序可以在插槽耗尽后向中央链表申请mspan:

如果空链表中没有可用的mspan,Go需要为中央链表获取新的mspan。新的mspan会从堆上分配并链接到中央链表上:

堆在需要时从OS中提取内存。如果需要更多内存,堆会分配一个叫做 arena 的大块内存, 在 64 位架构下为 64Mb,在其他架构下大多为 4Mb。arena 同样使用mspan来映射内存:

大分配

Go并不适用本地缓存来管理较大的内存空间分配。对于超过 32kb 的分配,会向上取整到页的大小,并直接从堆上分配。

全景图

现在我们对内存分配的时候发生了什么有了更好的认识。现在将所有的组成部分放在一起来得到全景图:

编译整理自 Go: Memory Management and Allocationhttps://medium.com/a-journey-with-go/go-memory-management-and-allocation-a7396d430f44

multiprocessing.manager管理的对象需要加锁吗_Go: 内存管理和分配相关推荐

  1. multiprocessing.manager管理的对象需要加锁吗_iOS内存管理布局-理论篇

    苹果设备备受欢迎的背后离不开iOS优秀的内存管理机制,那iOS的内存布局及管理方案是怎样的呢?我们一起研究下. 内存管理分为五大块 栈区(stack):线性结构,内存连续,系统自己管理内存,程序运行记 ...

  2. multiprocessing.manager管理的对象需要加锁吗_iOS内存管理布局及管理方案理论篇

    苹果设备备受欢迎的背后离不开iOS优秀的内存管理机制,那iOS的内存布局及管理方案是怎样的呢?我们一起研究下. 内存管理分为五大块 栈区(stack):线性结构,内存连续,系统自己管理内存,程序运行记 ...

  3. Linux内存管理:一个故事看懂CPU内存管理技术

    目录 8086 32位时代 虚拟内存 分页交换 现在 往期热门回顾 推荐阅读 还记得我吗,我是阿Q,CPU一号车间的那个阿Q. 今天忙里偷闲,来到厂里地址翻译部门转转,负责这项工作的小黑正忙得满头大汗 ...

  4. Spark 内存管理详解(下):内存管理

    本文转自:Spark内存管理详解(下)--内存管理 本文最初由IBM developerWorks中国网站发表,其链接为Apache Spark内存管理详解 在这里,正文内容分为上下两篇来阐述,这是下 ...

  5. 操作系统4小时速成:内存管理,程序执行过程,扩充内存,连续分配,非连续分配,虚拟内存,页面替换算法

    操作系统4小时速成:内存管理,程序执行过程,扩充内存,连续分配,非连续分配,虚拟内存,页面替换算法 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测 ...

  6. python中内存管理机制一共分为多少层_python 内存管理机制

    内存管理机制 ​python中万物皆对象,python的存储问题是对象的存储问题,并且对于每个对象,python会分配一块内存空间去存储它 ​Python的内存管理机制:引入计数.垃圾回收.内存池机制 ...

  7. Java内存管理和客户加载过程_Java内存管理的进一步理解-模拟过程图解

    java的内存管理分为: 1.堆内存:2.栈内存:3.方法区:4.本地方法区 下面通过一个简单的代码示例,理解Java中,内存是怎么进行分配与管理的.示例如下: public classJavaRam ...

  8. python内存管理错误的是_解读Python内存管理机制(转载)

    内存管理,对于Python这样的动态语言,是至关重要的一部分,它在很大程度上甚至决定了Python的执行效率,因为在Python的运行中,会创建和销毁大量的对象,这些都涉及到内存的管理. 小块空间的内 ...

  9. arm的linux怎么管理任务,【linux】arm mm内存管理

    欢迎转载,转载时请保留作者信息,谢谢. arm mmu硬件原理 由上图,arm分四种模式,section,大小页+ 极小页,  section模式简单,也能说明mmu本质,其它模式只是用了多级数组索引 ...

最新文章

  1. 计算机网络系统集成策略实现摘要,计算机网络集成策略实现探析
  2. Lakehouse 架构解析与云上实践
  3. nginx配置url重写
  4. java实现傅里叶变换
  5. cdn回源php_别让CDN的回源把你的服务器拖垮,采用正确的回源策略
  6. java类库支持_第十二章:开发支持类库
  7. 济南python工资一般多少-济南Go全栈区块链课程
  8. Tomcat 系统架构与设计模式之设计模式篇
  9. 背包问题 装箱问题 货盘装填问题 区别
  10. 水经注万能地图下载器怎么设置系统参数
  11. powerapps简介
  12. CSS盒模型完整介绍
  13. 【MapReuce】读取本地美国疫情数据存储结果到MySQL
  14. median _matlab 中值滤波函数
  15. 计算机打不开硬盘,硬盘打不开的原因和解决方法
  16. 华为云教程(云数据库RDS)
  17. [再寄小读者之数学篇](2014-05-30 对数不等式)
  18. iQQ 学习笔记1 :登录、验证码、收消息
  19. swagger Could not resolve pointer: /definitions/Person does not exist in document
  20. PaddleOCR车牌检测识别训练、部署

热门文章

  1. 转型产品经理该怎么做(适用于0-2岁的产品经理)
  2. excel使用MySQL数据,如何使用mysql完成excel中的数据生成
  3. python怎么改目录_如何查看文件,而不是使用Python进行更改的目录?
  4. webstorm中vue项目--运行配制
  5. jsp实现上一页下一页翻页功能
  6. 深入解析jQuery中的延时对象的概念
  7. HashSet源码分析:JDK源码系列
  8. TJOI2018Party
  9. django用户认证系统——登录4
  10. python函数-函数进阶