Go 当切换到新的G时,P是否会将McCache复制到G堆栈?
在Go的GMP(goroutine,system thread,context)模型中,goroutine可能会生成许多对象并将它们放入p(heap memory?)中,p上的所有数据会在G停止时复制到G的堆栈中吗?如果是这样,G的堆栈可能会变得非常大,这使得P的设计看起来毫无意义,但如果不是这样,调度程序如何解决多G的数据同时存储在P中的问题?如果G想在另一个P上执行,这是不可能的。 我的问题是Go 当切换到新的G时,P是否会将McCache复制到G堆栈?,go,goroutine,Go,Goroutine,在Go的GMP(goroutine,system thread,context)模型中,goroutine可能会生成许多对象并将它们放入p(heap memory?)中,p上的所有数据会在G停止时复制到G的堆栈中吗?如果是这样,G的堆栈可能会变得非常大,这使得P的设计看起来毫无意义,但如果不是这样,调度程序如何解决多G的数据同时存储在P中的问题?如果G想在另一个P上执行,这是不可能的。 我的问题是 当G停驻时,所有数据是否会复制到G'堆栈 为什么不在执行G时将所有数据放在G上 在您的问题中有一个
在您的问题中有一个基本的误解:
mcache
不是堆栈的占位符,它是堆上小型分配的捷径。它保存预先分配的内存块,这些内存块可以分发给特定的goroutine,从而避免锁定
编译器决定是否必须在堆上分配特定变量。一旦这样做,它将永远不会被复制回堆栈
现在的问题是如何尽可能有效地从堆中分配内存。这就是mcache
、mcentral
和mheap
的用武之地
是各种大小的预分配块的列表,每个处理器有一个mcache
P。由于P一次运行一个goroutineG,因此来自mcache
的分配不需要锁定mcache
- 如果
用完了预先分配的块,则会从mcache
请求更多的块,该块在Ps之间共享mcentral
- 如果
用完,则会从mcentral
请求更多的块,这反过来可能会从操作系统请求更多内存mheap
- 如果请求的块足够大,则直接从
请求它们mheap
mcache
、mcentral
和mheap
获得的所有内存段都是堆的一部分,它们可以被G使用,无论运行在哪个P上,当不再使用时,它们必须被垃圾收集
关于堆内存分配的更多详细信息,请参见以下内容:
mcache
不是“数据存储”,它只是一些可用内存块的记录。给定Pmcache
中的条目将被标记为已分配并提供给goroutine。但并没有任何东西能把这部分记忆和给定的P联系起来,它只是计算。