第1页
Go 1.4 runtime
Gopher China 2015
第2页
1. Memory Allocator 2. Garbage Collector 3. Goroutine Scheduler
第3页
1. Memory Allocator 内存分配器
第4页
base on tcmalloc.
基于成熟方案,性能优秀。随着版本升级, 针对性改进,以期与垃圾回收器更好协作。
核心:自主管理,缓存复用,无锁分配。
第5页
page, span.
内存管理以页为基本单位,多个地址连续 页构成内存块。
span1
8K 8K 8K
VA
span2
8K 8K
第6页
small, large.
以 32KB 为界,将对象分成大小两类。
page large object
span
切分
obojbeojcbestjcmetcatll
管理 分配
第7页
size class.
按 8 倍数,将小对象分成多种大小规格。
[1] 8 [2] 16 ... ... class size
span
等⻓长切分
3 6
8 1
第8页
heap, central, cache.
三级管理机构。
lock heap
向 OS 申请内存。
管理空闲 span。
lock central[1]
每个对应⼀一种 sizeclass。
...
central[n]
从 heap 获取 span,切分。
管理未全部回收的 span。
lock free
cache
从 central 获取 span。
...
cache
与线程绑定,⽆无锁分配。
第9页
init.
算法依赖连续地址,预留较大地址空间。
0xC000000000 128MB
spans
8GB
bitmap
AMD64: RESERVE RANGE 128GB
arena
块记录区域
垃圾回收标记区域
------------
按⻚页保存 span 指针。
反查 object 所属 span。
检查相邻 span 是否可合并。
⽤用户内存分配区域
VA
第10页
malloc.
快速分配,按需扩张。
OS
64K, 1MB
heap
span
central
span
large object
span (objects)
grow
small object
malloc
cache
第11页
sweep.
垃圾回收器引发回收操作。
large
GC
small
heap
ref = 0
ref != 0
span
相邻合并
X
OS
central
span/objects
cache
第12页
fixalloc.
为管理对象分配内存,不占用预留地址。
span
arena mem
cache
span
...
span: 管理内存块的元数据。 allspans: 垃圾回收遍历。
第13页
2. Garbage Collector 垃圾回收器
第14页
gc.
阈值触发,并行标记,并发清理。 定期强制回收,释放物理内存。
版本升级,垃圾回收效率总是核心问题。
第15页
gogc.
阈值检查,或强制回收。
malloc
next_gc
forcegc
2m
runtime.gc() 2
gogc
stop mark start sweep
stop mark sweep start
第16页
mark.
暂停用户逻辑,并行标记。
mark mark mark
stoptheworld starttheworld?
Go 1.5: concurrent pauseless collector.
markroot scanblock heap.bitmap
data bss finalizer
span span cache cache
… …
stack stack GG
… …
第17页
sweep.
串行,或与用户逻辑并发执行。
goroutine
gc
eagersweep
concurrent
bgsweep
mem allocator
sweepone
all spans
starttheworld
第18页
sysmon.
如阈值过大,可能会导致长时间无法触发 垃圾回收。因此,每 2 分钟强制检查回收 是非常必要的。
每 5 分钟,释放堆中长时间闲置块的物理 内存。
在系统初始化时,使⽤用专门的线程在后台运⾏行监控循环。
第19页
madvise.
在类 UNIX 系统,通过建议操作系统内核 解除内存映射的方式释放物理内存,但不 回收虚拟内存。
再次使用时,因缺页异常,由内核重新分 配物理内存。
Microsoft Windows 系统不⽀支持 madvise。
第20页
3. Goroutine Scheduler 并发调度器
第21页
goroutine.
轻量级实现,支持创建成千上万并发任务。
线程多路复用。 极小自定义初始栈。 任务在多个线程间切换。
第22页
scheduler.
三种抽象模型协作。
scheduler
thread
M
processor
P
VM
thread
CPU core
goroutine
G
task
第23页
max.
系统限制,允许调整。
scheduler
max = 10000
M
runtime/debug.SetMaxThreads
超出限制,会导致进程崩溃。
max = 256
P
runtime.GOMAXPROCS
调整 P 数量,会导致 G 任务队列重新分布。
G
第24页
newproc.
创建新并发任务。
go func()
newproc
G
fget malg stack
P
weakup
queue batch move
M
global queue
第25页
newm.
创建系统线程执行任务。
g0 stack
newm
M
checkmcount
mget
sched.midle
newosproc(g0)
system thread
第26页
execute.
并发任务调度执行。
weakup
M
mstart
P
schedule
goexit
local global netpoll steal
batch move
G
func gogo
execute
第27页
copystack.
连续栈替代分段栈。
segmented stack
system
stack
top
system
stack
top
contiguous stack
guard
fixed/min stack
memmove
guard
copy stack
2X
morestack
shrinkstack
第28页
4. channel, defer...
请参考拙作《学习笔记》
https://github.com/qyuhen/book
第29页
谢谢!
qyuhen.slack.com qyuhen@hotmail.com