簡體   English   中英

Go memory 分配 - 新對象、指針和轉義分析

[英]Go memory allocation - new objects, pointers and escape analysis

我讀到 Golang 語言以一種智能的方式管理 memory。 使用逃逸分析,go 在調用 new 時可能不會分配 memory,反之亦然。 golang 可以用這樣的符號var bob * Person = & Person {2, 3}分配 memory 。 或者指針總是指向棧

指針可能會逃到堆中,也可能不會,這取決於您的用例。 編譯器非常聰明。 例如給定:

type Person struct {
    b, c int
}


func foo(b, c int) int {
    bob := &Person{b, c}
    return bob.b
}

function foo將被編譯成:

    TEXT    "".foo(SB)
    MOVQ    "".b+8(SP), AX
    MOVQ    AX, "".~r2+24(SP)
    RET

這一切都在堆棧上,因為即使bob是一個指針,它也不會逃避這個函數的 scope。

但是,如果我們考慮一個輕微的(盡管是人為的)修改:

var globalBob *Person

func foo(b, c int) int {
    bob := &Person{b, c}
    globalBob = bob
    return bob.b
}

然后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

如您所見,它調用newobject


這些反匯編列表由https://godbolt.org/生成,適用於 amd64 上的 go 1.16

memory 是在堆棧上分配還是“逃逸”到堆上完全取決於您如何使用 memory,而不取決於您如何聲明變量。

如果您返回指向堆棧分配變量的指針,例如 C,則當您嘗試使用指針時,指針的值將無效。 這在 Go 中是不可能的,因為您無法明確告訴 Go 放置變量的位置。 它在選擇正確位置方面做得非常好,如果它發現對 memory 的 blob 的引用可能超出堆棧幀,它將確保分配發生在堆上。

golang可以用這樣的符號分配memory嗎

var bob * Person = & Person {2, 3}

或者指針總是指向棧

那行代碼不能說“總是”指向堆棧,但有時它可能會,所以是的,它可能會分配 memory (在堆上)。

同樣,這不是關於那行代碼,而是關於它之后的內容。 如果返回bob的值( Person對象的地址),則無法在堆棧上分配它,因為返回的地址將指向回收的 memory。

簡而言之,如果編譯器可以證明可以在堆棧上安全地創建該值,那么它將(可能)在堆棧上創建。 否則,它將在堆上分配。

編譯器用來做這些證明的工具非常好,但它並不總是正確的。 然而,大多數時候,擔心它的成本與收益並沒有真正的好處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM