內存逃逸

在C中

int *stackref()
{
    int val;
    return &val;
}

val是棧上的局部變量,返回其指針是明顯錯誤的。

而go的編譯器則會進行逃逸分析,如下代碼

func stackref() *int {
    var val int
    return &val
}

使用 go tool compile -S -m -l輸出匯編

test.go:4: moved to heap: val
test.go:5: &val escapes to heap
"".stackref t=1 size=64 value=0 args=0x8 locals=0x10
    0x0000 00000 (main.go:3)    TEXT    "".stackref(SB), $16-8
    0x0000 00000 (main.go:3)    MOVQ    (TLS), CX
    0x0009 00009 (main.go:3)    CMPQ    SP, 16(CX)
    0x000d 00013 (main.go:3)    JLS 50
    0x000f 00015 (main.go:3)    SUBQ    $16, SP
    0x0013 00019 (main.go:3)    FUNCDATA    $0, gclocals·5184031d3a32a42d85027f073f873668(SB)
    0x0013 00019 (main.go:3)    FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x0013 00019 (main.go:4)    LEAQ    type.int(SB), BX
    0x001a 00026 (main.go:4)    MOVQ    BX, (SP)
    0x001e 00030 (main.go:4)    PCDATA  $0, $0
    0x001e 00030 (main.go:4)    CALL    runtime.newobject(SB)
    0x0023 00035 (main.go:4)    MOVQ    8(SP), BX
    0x0028 00040 (main.go:5)    MOVQ    BX, "".~r0+24(FP)
    0x002d 00045 (main.go:5)    ADDQ    $16, SP
    0x0031 00049 (main.go:5)    RET
    0x0032 00050 (main.go:5)    NOP
    0x0032 00050 (main.go:3)    CALL    runtime.morestack_noctxt(SB)
    0x0037 00055 (main.go:3)    JMP 0

可以看到,編譯器檢測到了val的逃逸,調用runtime.newobject分配在了堆上。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容