Go gc如何处理堆分配?

Go gc如何处理堆分配?,go,Go,gc-Go(特别是go1.11)是预先分配一块内存并在每次分配时从中获取(比如JVM),还是每次创建变量时都进行分配,还是内核调用(malloc) 如果是每次分配一个内核调用,那么创建变量的成本就会很高。如何在堆栈/堆上强制分配?这在许多地方都有介绍,例如: 如何知道是在堆上还是在堆栈上分配变量? 从正确性的角度来看,您不需要知道。每个变量 只要存在对它的引用,in Go就存在。仓库 实现选择的位置与语义无关 这种语言的特点 存储位置确实会影响写入效率 程序。如果可能,Go编译器将分配 是该函数

gc-Go(特别是go1.11)是预先分配一块内存并在每次分配时从中获取(比如JVM),还是每次创建变量时都进行分配,还是内核调用(malloc)


如果是每次分配一个内核调用,那么创建变量的成本就会很高。如何在堆栈/堆上强制分配?

这在许多地方都有介绍,例如:

如何知道是在堆上还是在堆栈上分配变量?

从正确性的角度来看,您不需要知道。每个变量 只要存在对它的引用,in Go就存在。仓库 实现选择的位置与语义无关 这种语言的特点

存储位置确实会影响写入效率 程序。如果可能,Go编译器将分配 是该函数的堆栈帧中的函数的局部。然而,如果 编译器无法证明变量在之后未被引用 函数返回后,编译器必须在 垃圾收集堆以避免悬空指针错误。还有,如果 局部变量非常大,存储它可能更有意义 在堆上而不是堆栈上

在当前的编译器中,如果一个变量的地址被占用,那么 变量是堆上分配的候选变量。然而,一个基本的 转义分析可以识别某些情况下,这些变量不会 live超过函数的返回,可以驻留在堆栈上



Go的内存分配经过仔细优化,以满足其需求,例如使用一个。我怀疑你有一个稍微不同的基本问题/你正在努力解决的问题-最好还是问这个问题。如果这只是探索/好奇,那么您必须使问题更加具体。

分配器是特定于实现的,并且随着时间的推移而变化。在通用实现中,不能强制堆栈上的分配,但可以尝试阻止它们转义。在需要的时候,在堆栈中保留分配通常不太困难。要理解@JimB所说的,编译器非常擅长转义分析。任何从未离开分配函数的变量都应该位于堆上(这并不困难,因为Go通过复制传递)。@JimB我更新了这个问题,因为我主要关注gc Go 1.11。你能详细说明一下如何“在堆栈中保持分配”吗?go 1.12正在使用中beta@texasbruce:如果某个值对于堆栈来说不是太大,并且没有超出函数的范围,则通常在堆栈上分配该值。如果你想在一个特定的版本中了解这方面的具体细节,最好询问邮件列表。如果你实际上还没有问题,那么就没有理由担心理论上的分配没有发生。