我读到 Golang 语言以一种智能的方式管理内存。使用逃逸分析,go在调用new时可能不会分配内存,反之亦然。golang可以用这样的表示法分配内存吗var bob * Person = & Person {2, 3}?或者指针总是指向堆栈
指针可能会逃逸到堆,也可能不会,具体取决于您的用例。编译器非常聪明。例如给出:
type Person struct {
b, c int
}
func foo(b, c int) int {
bob := &Person{b, c}
return bob.b
}
Run Code Online (Sandbox Code Playgroud)
该函数foo将被编译为:
TEXT "".foo(SB)
MOVQ "".b+8(SP), AX
MOVQ AX, "".~r2+24(SP)
RET
Run Code Online (Sandbox Code Playgroud)
它都在这里的堆栈上,因为即使bob是一个指针,它也不会逃脱这个函数的作用域。
然而,如果我们考虑一个轻微的(尽管是人为的)修改:
var globalBob *Person
func foo(b, c int) int {
bob := &Person{b, c}
globalBob = bob
return bob.b
}
Run Code Online (Sandbox Code Playgroud)
然后bob转义,并foo会被编译为:
TEXT "".foo(SB), ABIInternal, $24-24
MOVQ (TLS), CX
CMPQ SP, 16(CX)
PCDATA $0, $-2
JLS foo_pc115
PCDATA $0, $-1
SUBQ $24, SP
MOVQ BP, 16(SP)
LEAQ 16(SP), BP
LEAQ type."".Person(SB), AX
MOVQ AX, (SP)
PCDATA $1, $0
CALL runtime.newobject(SB)
MOVQ 8(SP), AX
MOVQ "".b+32(SP), CX
MOVQ CX, (AX)
MOVQ "".c+40(SP), CX
MOVQ CX, 8(AX)
PCDATA $0, $-2
CMPL runtime.writeBarrier(SB), $0
JNE foo_pc101
MOVQ AX, "".globalBob(SB)
foo_pc83:
PCDATA $0, $-1
MOVQ (AX), AX
MOVQ AX, "".~r2+48(SP)
MOVQ 16(SP), BP
ADDQ $24, SP
RET
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这会调用newobject.
这些反汇编列表由https://godbolt.org/生成,适用于 amd64 上的 go 1.16