在GPM关系中,会在每个 P
下都有一个 mcache
字段,用来表示内存信息。
在 Go 1.2 版本以前调度器使用的是 GM 模型,将 mcache
放在了 M 里,但发现存在诸多问题,其中对于内存这一块存在着巨大的浪费。每个 M 都持有 mcache
和 stack alloc,但只有在 M 运行 Go 代码时才需要使用内存(每个 mcache
可以高达2mb),当 M 在处于 syscall 或 网络请求 的时候是不需要内存的,再加上 M 又是允许创建多个的,这就造成了内存的很大浪费。所以从go 1.3版本开始使用了GPM模型,这样在高并发状态下,每个G只有在运行的时候才会使用到内存,而每个 G 会绑定一个P,所以它们在运行时只占用一份 mcache
,对于 mcache
的数量就是P 的数量,同时并发访问时也不会产生锁。