MST

星途 面试题库

面试题:Go中堆与栈在变量存储上的区别

在Go语言中,简要阐述堆和栈在变量存储方面有哪些不同?并举例说明什么样的变量通常存储在堆上,什么样的变量存储在栈上。
25.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

堆和栈在变量存储方面的不同

  1. 分配方式
    • :栈上的变量分配和释放非常高效,遵循后进先出(LIFO)原则。当一个函数调用时,其局部变量在栈上被分配空间,函数返回时,这些变量所占用的栈空间被自动释放。
    • :堆上的内存分配相对复杂,需要通过垃圾回收(GC)机制来管理内存的释放。Go语言的垃圾回收器会定期扫描堆内存,回收不再被引用的对象所占用的空间。
  2. 内存管理
    • :由编译器自动管理,不需要程序员手动干预内存的分配和释放,因此栈上变量的生命周期与函数调用紧密相关。
    • :由于垃圾回收机制的存在,堆上变量的生命周期由垃圾回收器决定,只要变量还被引用,垃圾回收器就不会回收其占用的内存。

变量存储位置示例

  1. 存储在堆上的变量
    • 一般来说,通过new关键字或者make关键字创建的对象会存储在堆上。例如:
    package main
    
    import "fmt"
    
    func main() {
        // 使用new创建一个指向int类型的指针,该指针指向的int值存储在堆上
        var numPtr *int = new(int)
        *numPtr = 10
        fmt.Println(*numPtr)
    
        // 使用make创建一个切片,切片底层的数据结构存储在堆上
        slice := make([]int, 0, 10)
        slice = append(slice, 1, 2, 3)
        fmt.Println(slice)
    }
    
  2. 存储在栈上的变量
    • 函数内部的局部变量,如果其大小在编译时可以确定,并且没有被逃逸分析判定为需要在堆上分配,那么这些变量会存储在栈上。例如:
    package main
    
    import "fmt"
    
    func add(a, b int) int {
        // 局部变量sum存储在栈上
        sum := a + b
        return sum
    }
    
    func main() {
        result := add(3, 5)
        fmt.Println(result)
    }
    

add函数中,sum变量是局部变量,其大小在编译时已知,并且没有逃逸出函数,因此存储在栈上。