面试题答案
一键面试- 优化思路:
- 在Go语言中,当一个变量的内存分配在堆上而不是栈上时,就发生了内存逃逸。对于较大的结构体作为函数参数,如果直接传递结构体值,由于其较大可能会导致内存逃逸到堆上。
- 可以通过传递指针来优化。传递指针时,在函数调用栈上只需要存储指针本身的大小(通常是机器字长,如64位系统上为8字节),而不是整个结构体的大小,这样可以减少栈空间的占用,并且有可能避免内存逃逸。
- 实现方式:
- 原方式(传递结构体值):
package main
import "fmt"
// 定义一个较大的结构体
type BigStruct struct {
Data [1000]int
}
// 接受结构体值作为参数的函数
func ProcessValue(s BigStruct) {
// 对结构体进行处理
fmt.Println(s.Data[0])
}
- 优化方式(传递结构体指针):
package main
import "fmt"
// 定义一个较大的结构体
type BigStruct struct {
Data [1000]int
}
// 接受结构体指针作为参数的函数
func ProcessPointer(s *BigStruct) {
// 对结构体进行处理
fmt.Println(s.Data[0])
}
- 调用函数:
func main() {
big := BigStruct{}
// 使用传递值的方式调用函数
ProcessValue(big)
// 使用传递指针的方式调用函数
ProcessPointer(&big)
}
在实际应用中,通过使用go build -gcflags '-m'
命令可以查看是否发生内存逃逸。传递指针的方式更有可能避免因传递大结构体值而导致的内存逃逸。但要注意,传递指针时要确保指针的有效性,避免空指针引用。同时,如果函数需要修改结构体内容,传递指针也是更合适的选择。