MST

星途 面试题库

面试题:Go语言中,如何通过代码示例判断是否发生内存逃逸?

请举例说明在Go代码中,哪些常见的情况会导致内存逃逸,并给出相应的代码示例,同时说明如何借助工具判断代码是否存在内存逃逸现象。
25.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

常见导致内存逃逸的情况及代码示例

  1. 返回局部变量指针
package main

func allocate() *int {
    num := 10
    return &num
}

在上述代码中,allocate 函数返回了局部变量 num 的指针。由于函数返回后,调用者可能还会使用这个指针,所以 num 不能在栈上分配,只能逃逸到堆上。

  1. 传递给接口类型参数
package main

type Number interface{}

func passToInterface(i Number) {}

func main() {
    num := 10
    passToInterface(num)
}

这里 num 被传递给了 passToInterface 函数,其参数类型是接口类型 Number。因为在编译时无法确定 num 在接口中的具体使用方式,所以 num 会逃逸到堆上。

  1. 动态大小的切片
package main

func growSlice() []int {
    var s []int
    for i := 0; i < 10; i++ {
        s = append(s, i)
    }
    return s
}

growSlice 函数中,s 是一个动态大小的切片。由于切片的大小在编译时不确定,并且在函数执行过程中可能会不断增长,所以 s 会逃逸到堆上。

借助工具判断内存逃逸现象

在Go中,可以使用 go build 命令的 -gcflags 选项来查看内存逃逸分析结果。例如:

go build -gcflags '-m'

执行上述命令后,编译输出中会包含逃逸分析信息,如下所示:

# command-line-arguments
./main.go:4:13: &num escapes to heap
./main.go:3:6: moved to heap: num

上述输出表明 num 变量逃逸到了堆上。如果想获取更详细的信息,可以使用 -m -m 选项,即:

go build -gcflags '-m -m'

这样会输出更详细的逃逸分析信息,帮助开发者更准确地定位和理解内存逃逸问题。