Golang内存逃逸引发的面试考察点

Golang内存逃逸引发的面试考察点

什么是内存逃逸?

在go语言中每个goroutine都会有一个自己的栈区,每个栈区呢又会对应多个栈帧,每个栈帧就会对应一个函数,这个栈帧就是用来存储函数的局部变量、入参、返回地址等等。这些变量就会随着函数的运行结束而自动销毁。编译期会对相关变量会做一个分析,有些场景下变量就不会存入到栈帧而是会分配到堆上面,这个过程就是逃逸分析。

逃逸分析有什么作用?

帮助编译器优化内存分配和回收效率

哪些场景下会发生逃逸呢?

  • 函数返回局部变量的指针
  • 函数指针类型的入参
  • 闭包访问的函数外部变量
  • 动态变量类型
  • 变量大小不确定时
  • 栈空间不足存放变量内存时

有什么办法可以确认变量是否发生逃逸?

通过 go run -gcflags="-m -m" you_file.go 命令 PS:go run 和 go build都可以

堆栈分别有什么特点

  • 栈是一种自动分配和释放内存的数据结构,用于保存函数的局部变量、函数参数和函数调用返回时的临时数据
  • 栈的分配和释放速度非常快,因为它只需要简单移动下栈指针
  • 栈的大小在编译器就确定了且是固定不可改变的
  • 栈上的变量的生命周期是与其对应函数的相对应的
  • 栈上的内存是有限的并且是线程私有的不会存在并发访问问题
  • 栈上存储的数据大小通常比较小,适用于存储基本数据类型和短期临时变量

  • 堆是动态分配的内存区域,用于存储程序运行时动态创建的数据结构体和对象等
  • 堆的分配和释放稍微慢一点,因为需要在堆上进行复杂的内存管理操作,例如三色标记
  • 堆的大小通常比较大,取决于运行时的需求,它的生命周期可以比较长
  • 堆上的内存需要手动进行释放,不然会造成内存泄露
  • 堆上的数据可以被多个线程共享,因此需要在并发访问时进行加锁
  • 堆适用于存储大量数据或者需要动态扩展的数据结构

你可能感兴趣的:(go,golang,面试)