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