内存逃逸

在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分配在了堆上。

你可能感兴趣的:(内存逃逸)