Go 当切换到新的G时,P是否会将McCache复制到G堆栈?

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上 在您的问题中有一个

在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
      是各种大小的预分配块的列表,每个处理器有一个
      mcache
      P。由于P一次运行一个goroutineG,因此来自
      mcache
      的分配不需要锁定
    • 如果
      mcache
      用完了预先分配的块,则会从
      mcentral
      请求更多的块,该块在Ps之间共享
    • 如果
      mcentral
      用完,则会从
      mheap
      请求更多的块,这反过来可能会从操作系统请求更多内存
    • 如果请求的块足够大,则直接从
      mheap
      请求它们
    所有这些都是为了避免在小内存分配期间锁定。但是从
    mcache
    mcentral
    mheap
    获得的所有内存段都是堆的一部分,它们可以被G使用,无论运行在哪个P上,当不再使用时,它们必须被垃圾收集

    关于内存分配的更多详细信息,请参见以下内容:


    感谢您的评论,我会将此添加到我的问题中,希望对我的问题进行更深入的解释请注意,您的问题没有多大意义,因为这不是语言指定的,任何编译器(针对每个体系结构和每个版本)可能会完全不同。嗯,gc和gcc在任何操作系统上针对amd和arm时使用相同的机制。也许WASM也是,但我不确定。谢谢你的回答,我正在研究这些帖子。“G可以使用它们,无论它在哪个P上运行”留下了一个问题,如果一个goroutine在一个mcache上留下了一些数据,现在它转到另一个P,如果它想写入旧数据,它会被分配到当前的mcache吗?
    mcache
    不是“数据存储”,它只是一些可用内存块的记录。给定P
    mcache
    中的条目将被标记为已分配并提供给goroutine。但并没有任何东西能把这部分记忆和给定的P联系起来,它只是计算。