前言 //todo 后续有空在写

本系列基于golang 1.20.4版本 go的内存分配采用tcmalloc的分配机制,为我们go运行时分配堆内存。
在linux中,分配内存有两种方式,brk与mmap

  • brk:将数据段最高指针地址往高处推,分配连续内存(默认小于128K)
  • mmap:分配一块空闲的虚拟内存,多次不连续
  • madvise:回收内存
//runtime/mem.go 仅展示方法
//从os分配块内存
func sysAlloc(n uintptr, sysStat *sysMemStat) unsafe.Pointer {}
//释放内存
func sysUnused(v unsafe.Pointer, n uintptr) {}
//通知操作系统需要使用该区域内存,保证安全访问
func sysUsed(v unsafe.Pointer, n, prepared uintptr) {}
//使用大页内存
func sysHugePage(v unsafe.Pointer, n uintptr) {}
//oom时无条件返回内存
func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {}
//转换为保留状态
func sysFault(v unsafe.Pointer, n uintptr) {}
//保留该内存,访问触发异常
func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {}
//转换至就绪状态
func sysMap(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {}

go通过syscall与系统进行交互,并根据不同平台基于平台实现了runtime/mem.go中的方法,且将大块内存分成了以下不同类型的结构存储

  • mcache:与p绑定,本地内存分配操作,不需要上锁
  • mcentral:中心分配缓存,分配时需要上锁,不同spanClass使用不同的锁
  • mheap:全局唯一,从os申请内存,并修改内存定义结构时,加全局锁
+----+     +-------+     +----------+     +--------+
| os | --> | mheap | --> | mcentral | --> | mcache |
+----+     +-------+     +----------+     +--------+

mcache

// Initialize the heap.
func (h *mheap) init() {
	lockInit(&h.lock, lockRankMheap)
	lockInit(&h.speciallock, lockRankMheapSpecial)

	h.spanalloc.init(unsafe.Sizeof(mspan{}), recordspan, unsafe.Pointer(h), &memstats.mspan_sys)
	h.cachealloc.init(unsafe.Sizeof(mcache{}), nil, nil, &memstats.mcache_sys)
	h.specialfinalizeralloc.init(unsafe.Sizeof(specialfinalizer{}), nil, nil, &memstats.other_sys)
	h.specialprofilealloc.init(unsafe.Sizeof(specialprofile{}), nil, nil, &memstats.other_sys)
	h.specialReachableAlloc.init(unsafe.Sizeof(specialReachable{}), nil, nil, &memstats.other_sys)
	h.arenaHintAlloc.init(unsafe.Sizeof(arenaHint{}), nil, nil, &memstats.other_sys)

	// Don't zero mspan allocations. Background sweeping can
	// inspect a span concurrently with allocating it, so it's
	// important that the span's sweepgen survive across freeing
	// and re-allocating a span to prevent background sweeping
	// from improperly cas'ing it from 0.
	//
	// This is safe because mspan contains no heap pointers.
	h.spanalloc.zero = false
	// h->mapcache needs no init
	for i := range h.central {
		h.central[i].mcentral.init(spanClass(i))
	}
	h.pages.init(&h.lock, &memstats.gcMiscSys)
}

主要分为三种

  • Tiny: size<16 byte && noscan
  • Small scan || 16 bytes <= size <= 32 kb
  • Large: size > 32kb

中内存

大内存

栈内存

// class  bytes/obj  bytes/span  objects  tail waste  max waste  min align
//     1          8        8192     1024           0     87.50%          8
//     2         16        8192      512           0     43.75%         16
//     3         24        8192      341           8     29.24%          8
//     4         32        8192      256           0     21.88%         32
//     5         48        8192      170          32     31.52%         16
//     6         64        8192      128           0     23.44%         64
//     7         80        8192      102          32     19.07%         16
//     8         96        8192       85          32     15.95%         32
//     9        112        8192       73          16     13.56%         16
//    10        128        8192       64           0     11.72%        128
//    11        144        8192       56         128     11.82%         16
//    12        160        8192       51          32      9.73%         32
//    13        176        8192       46          96      9.59%         16
//    14        192        8192       42         128      9.25%         64
//    15        208        8192       39          80      8.12%         16
//    16        224        8192       36         128      8.15%         32
//    17        240        8192       34          32      6.62%         16
//    18        256        8192       32           0      5.86%        256
//    19        288        8192       28         128     12.16%         32
//    20        320        8192       25         192     11.80%         64
//    21        352        8192       23          96      9.88%         32
//    22        384        8192       21         128      9.51%        128
//    23        416        8192       19         288     10.71%         32
//    24        448        8192       18         128      8.37%         64
//    25        480        8192       17          32      6.82%         32
//    26        512        8192       16           0      6.05%        512
//    27        576        8192       14         128     12.33%         64
//    28        640        8192       12         512     15.48%        128
//    29        704        8192       11         448     13.93%         64
//    30        768        8192       10         512     13.94%        256
//    31        896        8192        9         128     15.52%        128
//    32       1024        8192        8           0     12.40%       1024
//    33       1152        8192        7         128     12.41%        128
//    34       1280        8192        6         512     15.55%        256
//    35       1408       16384       11         896     14.00%        128
//    36       1536        8192        5         512     14.00%        512
//    37       1792       16384        9         256     15.57%        256
//    38       2048        8192        4           0     12.45%       2048
//    39       2304       16384        7         256     12.46%        256
//    40       2688        8192        3         128     15.59%        128
//    41       3072       24576        8           0     12.47%       1024
//    42       3200       16384        5         384      6.22%        128
//    43       3456       24576        7         384      8.83%        128
//    44       4096        8192        2           0     15.60%       4096
//    45       4864       24576        5         256     16.65%        256
//    46       5376       16384        3         256     10.92%        256
//    47       6144       24576        4           0     12.48%       2048
//    48       6528       32768        5         128      6.23%        128
//    49       6784       40960        6         256      4.36%        128
//    50       6912       49152        7         768      3.37%        256
//    51       8192        8192        1           0     15.61%       8192
//    52       9472       57344        6         512     14.28%        256
//    53       9728       49152        5         512      3.64%        512
//    54      10240       40960        4           0      4.99%       2048
//    55      10880       32768        3         128      6.24%        128
//    56      12288       24576        2           0     11.45%       4096
//    57      13568       40960        3         256      9.99%        256
//    58      14336       57344        4           0      5.35%       2048
//    59      16384       16384        1           0     12.49%       8192
//    60      18432       73728        4           0     11.11%       2048
//    61      19072       57344        3         128      3.57%        128
//    62      20480       40960        2           0      6.87%       4096
//    63      21760       65536        3         256      6.25%        256
//    64      24576       24576        1           0     11.45%       8192
//    65      27264       81920        3         128     10.00%        128
//    66      28672       57344        2           0      4.91%       4096
//    67      32768       32768        1           0     12.50%       8192

1.1 goroutine

1.2 gmp调度模型

1.3 调度算法

1.4 goroutine生命周期