面试题答案
一键面试内存逃逸概念
在Go语言中,内存逃逸指的是原本可以在栈上分配的变量,由于某些原因被分配到了堆上。Go编译器会根据变量的作用域、是否被外部引用等因素决定变量分配在栈还是堆。如果变量在函数返回后依然被外部引用,就会发生内存逃逸,被分配到堆上。
内存逃逸引发内存泄漏的原因
当内存逃逸导致变量分配在堆上后,如果这些变量不再被使用,但程序没有正确释放它们所占用的内存,就可能引发内存泄漏。这是因为堆内存的管理相对复杂,一旦程序逻辑出现错误,没有及时回收不再使用的堆内存,随着程序运行,这些未释放的内存会不断累积,最终耗尽系统内存资源。
代码场景示例
package main
import "fmt"
func createLargeSlice() *[]int {
largeSlice := make([]int, 1000000)
return &largeSlice
}
func main() {
for {
slicePtr := createLargeSlice()
// 这里没有使用slicePtr指向的切片,也没有释放其内存
// 每次循环都会创建一个新的大切片并分配在堆上,且未释放
fmt.Println("Iteration")
}
}
在上述代码中,createLargeSlice
函数创建了一个大的整数切片,并返回其指针。在main
函数的无限循环中,不断调用该函数创建新的切片,但没有对这些切片进行任何实际使用,也没有释放它们的内存。由于切片指针被返回,发生了内存逃逸,切片被分配在堆上,随着循环不断进行,堆内存持续增加,最终可能导致内存泄漏。