相关博文 golang中slice扩容一定是double或1.25倍吗
较好博文:
本篇是对以上内容的学习与记录:
Go运行时的内存分配算法主要源自 Google 为 C 语言开发的TCMalloc算法,全称Thread-Caching Malloc。核心思想就是把内存分为多级管理,从而降低锁的粒度。它将可用的堆内存采用二级分配的方式进行管理:每个线程都会自行维护一个独立的内存池,进行内存分配时优先从该内存池中分配,当内存池不足时才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。
Go在程序启动时 先向操作系统申请一块内存,并将其分配到三个区域:
arena区域(512GB,64位操作系统),即堆区,Go动态分配的内存都在该区域,其将内存分割成8KB大小的页,一些页组合起来称为mspan
bitmap区域(16GB),标识arena区域哪些地址保存了对象,并用4bit标志位表示对象是否包含指针、GC标记信息。bitmap中一个byte大小的内存对应arena区域中4个指针大小(指针大小为 8B )的内存,所以bitmap区域的大小是512GB/(4*8B)=16GB
spans区域(512MB):存放mspan(arena分割的页组合起来的内存管理基本单元)的指针,每个指针对应一页,所以spans区域的大小就是512GB/8KB*8B=512MB。(除以8KB是计算arena区域的页数,而最后乘以8是计算spans区域所有指针的大小。创建mspan的时候,按页填充对应的spans区域,在回收object时,根据地址很容易就能找到它所属的mspan)
mspan 是Go内存管理的基本单元,mspan是由一片连续的8KB的页组成的大块内存。这里的页和操作系统本身的页不是一回事,它一般是操作系统页大小的几倍。即mspan是一个包含起始地址、mspan规格、页的数量等内容的双端链表
细微的对象切割
极致的多级缓存
精准的位图管理
更多:
Go里面的对象分配分为大对象、小对象、微对象。请详细介绍
在 Go 语言中,内存分配和管理是非常重要的,因为它直接影响了应用程序的性能。为了最大程度地提高应用程序的性能,Go 语言将对象分为三个不同的类别:大对象、小对象和微对象。
大对象(Large Objects):size > 32KB
大对象是指大于 32KB 的内存分配。在 Go 中,大对象使用连续的内存块进行分配。在分配内存时,Go 运行时会将大对象分配在堆上。由于大对象需要大量的连续内存块,因此在分配大对象时可能会发生内存碎片问题。
小对象(Small Objects):有指针 || 大小在16 Byte 到 32k Bytes之间
小对象是指小于 32KB 的内存分配。在 Go 中,小对象使用堆和栈进行分配。当分配小对象时,Go 运行时会将对象分配在栈上。当栈上的对象不再需要时,它们会自动被销毁。但是,当栈上的对象过多时,可能会导致栈溢出的问题。当对象太大时,Go 运行时会将对象分配在堆上。与大对象一样,小对象在分配时也可能会发生内存碎片问题。
微对象(Tiny Objects):size < 16 Bytes && 没有指针
微对象是指非常小的内存分配,通常小于 16 字节。在 Go 中,微对象使用内部缓存进行分配。这个内部缓存被称为 Tcache。Tcache 可以存储一定数量的微对象,以避免频繁地进行内存分配和释放,从而提高性能。当 Tcache 中的微对象被用尽时,Go 运行时会将对象分配在堆上。
总的来说,Go 运行时会根据对象的大小和类型,选择最合适的内存分配方式。通过这种方式,Go 语言可以在不影响性能的情况下,提供高效的内存分配和管理。
原文链接: https://dashen.tech/2010/03/24/Go内存管理之内存分配/
版权声明: 转载请注明出处.