MST

星途 面试题库

面试题:Go中如何初步判断一段代码是否可能发生内存逃逸

请阐述在Go语言中,从代码层面可以通过哪些特征初步判断一段代码可能会发生内存逃逸,例如函数返回局部变量指针这种情况,除此之外还有哪些常见情况,并简单说明原因。
39.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言中,除了函数返回局部变量指针会发生内存逃逸外,常见的可能导致内存逃逸的情况及原因如下:

  1. 在栈上分配大的数组:如果在函数内定义一个非常大的数组,编译器可能会为了避免栈溢出而将其分配到堆上。因为栈空间有限,大数组占用空间大,放栈上可能导致栈溢出。例如:
func largeArray() {
    a := make([]int, 1000000)
    // 使用a
}
  1. 闭包引用外部变量:闭包函数内部使用了外部函数的局部变量,为了保证闭包函数在外部函数返回后仍能正确访问这些变量,这些变量会逃逸到堆上。例如:
func outer() func() int {
    x := 10
    return func() int {
        return x
    }
}
  1. 参数为interface类型:当函数参数是interface类型时,由于编译器在编译期无法确定具体的类型,参数值会逃逸到堆上。例如:
func printAnything(i interface{}) {
    fmt.Println(i)
}
func main() {
    num := 10
    printAnything(num)
}
  1. 动态类型断言:在进行类型断言时,如果断言的类型在编译期不确定,相关的值可能会逃逸到堆上。例如:
func doSomething(i interface{}) {
    if s, ok := i.(string); ok {
        fmt.Println(s)
    }
}
  1. 使用go关键字启动协程:在协程中使用的局部变量,为了保证协程独立运行,这些变量会逃逸到堆上。例如:
func main() {
    var x int = 10
    go func() {
        fmt.Println(x)
    }()
}