golang内存分配与管理 您所在的位置:网站首页 go的内存分配机制 golang内存分配与管理

golang内存分配与管理

2023-08-15 03:12| 来源: 网络整理| 查看: 265

概述

​ golang的内存分配机制源自Google的tcmalloc算法,英文全称thread caching malloc,从名字可以看出,是在原有基础上,针对多核多线程的内存管理进行优化而提出来的。该算法的核心思想是内存的多级管理,进而降低锁的粒度;将内存按需划成大小不一的块,减少内存的碎片化。为每个P,也就是go协程调度模型了里面的逻辑处理器维护一个mcache结构体的独立内存池,只有当该内存池不足时,才会向全局mcentral和mheap结构体管理的内存池申请。为每一个P维持一个私有的本地内存池,从而不用加锁,加快了内存分配速度。只有在本地P的内存池被消耗完,或者申请的内存太大时,才会访问全局的内存池,大大减小了多线程下对全局内存池访问带来的竞争系统损耗。

内存架构

​ 以64位的系统为例,1.11版本以后go程序的整个堆内存是连续,如下图 所示。结构虽然简单,但是在混合使用go和c的时候会导致程序崩溃,例如分配的内存地址发生冲突,导致初始化堆和扩容失败。 在这里插入图片描述 ​ 自1.11版本以后,对堆实现了分块处理,arena不再是连续的,以64位的Linux系统为例,是一个块块64MB大小的块。golang内存的三级架构如下图所示。下面将分别介绍各个层。

在这里插入图片描述

mspan

​ mspan结构体是go内存管理的基本单元,定义在runtime/mheap.go中,主要结构体成员如下:

//go:notinheap type mspan struct { next *mspan // next span in list, or nil if none prev *mspan // previous span in list, or nil if none startAddr uintptr // address of first byte of span aka s.base() npages uintptr // number of pages in span nelems uintptr // number of object in the span. allocBits *gcBits allocCount uint16 // number of allocated objects spanclass spanClass // size class and noscan (uint8) elemsize uintptr // computed from sizeclass or from npages ..... }

​ 可以发现,这是一个双向链表。

​ startAddr:当前span在arena中的起始字节的地址

​ npages:当前span包含arena中多少页

​ nelems:当前span,包含多少个对象。golang又对每一个span,按照所属class的不同,切分成大小不同的块,以减少内存碎片。

​ allocCount:已分配的对象数目

​ elemsize:对象大小

​ spanclass:span所属的class。

​ 根据对象的大小,golang划分了一系列的class,以应对各种场景的内存分配,较少内存碎片化。每个class都有一个固定大小的对象和固定的span大小,如下所示:

// class bytes/obj bytes/span objects waste bytes // 1 8 8192 1024 0 // 2 16 8192 512 0 // 3 32 8192 256 0 // 4 48 8192 170 32 // 5 64 8192 128 0 // 6 80 8192 102 32 // 7 96 8192 85 32 // 8 112 8192 73 16 // 9 128 8192 64 0 // 10 144 8192 56 128 // 11 160 8192 51 32 // 12 176 8192 46 96 // 13 192 8192 42 128 // 14 208 8192 39 80 // 15 224 8192 36 128 // 16 240 8192 34 32 // 17 256 8192 32 0 // 18 288 8192 28 128 // 19 320 8192 25 192 // 20 352 8192 23 96 // 21 384 8192 21 128 // 22 416 8192 19 288 // 23 448 8192 18 128 // 24 480 8192 17 32 // 25 512 8192 16 0 // 26 576 8192 14 128 // 27 640 8192 12 512 // 28 704 8192 11 448 // 29 768 8192 10 512 // 30 896 8192 9 128 // 31 1024 8192 8 0 // 32 1152 8192 7 128 // 33 1280 8192 6 512 // 34 1408 16384 11 896 // 35 1536 8192 5 512 // 36 1792 16384 9 256 // 37 2048 8192 4 0 // 38 2304 16384 7 256 // 39 2688 8192 3 128 // 40 3072 24576 8 0 // 41 3200 16384 5 384 // 42 3456 24576 7 384 // 43 4096 8192 2 0 // 44 4864 24576 5 256 // 45 5376 16384 3 256 // 46 6144 24576 4 0 // 47 6528 32768 5 128 // 48 6784 40960 6 256 // 49 6912 49152 7 768 // 50 8192 8192 1 0 // 51 9472 57344 6 512 // 52 9728 49152 5 512 // 53 10240 40960 4 0 // 54 10880 32768 3 128 // 55 12288 24576 2 0 // 56 13568 40960 3 256 // 57 14336 57344 4 0 // 58 16384 16384 1 0 // 59 18432 73728 4 0 // 60 19072 57344 3 128 // 61 20480 40960 2 0 // 62 21760 65536 3 256 // 63 24576 24576 1 0 // 64 27264 81920 3 128 // 65 28672 57344 2 0 // 66 32768 32768 1 0

​ 其中:

​ class:是class id, 对应了span结构体所属的class的种类,可以看到一共66中,实际一共67种。大于32K的内存 分配,会直接从mheap中分配,后面会介绍。

​ bytes/obj:每个对象占用的字节数

​ bytes/span:每个span的大小,也就是页数*8k(页大小)

​ objects:该类span所拥有的对象数,span所占字节数/对象所占字节数

​ waste bytes:该类span浪费的字节数,从以上分析可以看出,每一类span并不能刚好按该类对象大小,分配整数个对象,即做到每一字节物尽其用,这个值是:span所占字节数%对象所占字节数

​ 以class 10 为例,span与管理的内存如下图所示:

在这里插入图片描述

表示当前span类别属于class10,大小只有1页,又切分56个大小为144字节的块,其中两个已分配。

mheap

​ mheap管理整个go程序的堆空间,在源文件runtime/mheap.go中找到了该结构体描述,以及全局变量mheap_,结构体主要字段如下:

type mheap struct { // lock must only be acquired on the system stack, otherwise a g // could self-deadlock if its stack grows with the lock held. lock mutex pages pageAlloc // page allocation data structure allspans []*mspan // all spans out there // Malloc stats. largealloc uint64 // bytes allocated for large objects nlargealloc uint64 // number of large object allocations central [numSpanClasses]struct { mcentral mcentral pad [cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize]byte } spanalloc fixalloc // allocator for span* cachealloc fixalloc // allocator for mcache* curArena struct { base, end uintptr } arenas [1


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有