Stack vs heap allocation of structs in Go, and how they relate to garbage collection

前端 未结 5 1069
谎友^
谎友^ 2020-11-30 16:19

I\'m new to Go and I\'m experiencing a bit of congitive dissonance between C-style stack-based programming where automatic variables live on the stack and allocated memory l

5条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-30 17:02

    func Function1() (*MyStructType, error) {
        var chunk *MyStructType = new(HeaderChunk)
    
        ...
    
        return chunk, nil
    }
    
    
    func Function2() (*MyStructType, error) {
        var chunk MyStructType
    
        ...
    
        return &chunk, nil
    }
    

    Function1 and Function2 may be inline function. And return variable will not escape. It's not necessary to allocate variable on the heap.

    My example code:

     1  package main
     2  
     3  type S struct {
     4          x int
     5  }
     6  
     7  func main() {
     8          F1()
     9          F2()
    10          F3()
    11  }
    12  
    13  func F1() *S {
    14          s := new(S)
    15          return s
    16  }
    17  
    18  func F2() *S {
    19          s := S{x: 10}
    20          return &s
    21  }
    22  
    23  func F3() S {
    24          s := S{x: 9}
    25          return s
    26  }
    

    According to output of cmd:

    go run -gcflags -m test.go
    

    output:

    # command-line-arguments
    ./test.go:13:6: can inline F1
    ./test.go:18:6: can inline F2
    ./test.go:23:6: can inline F3
    ./test.go:7:6: can inline main
    ./test.go:8:4: inlining call to F1
    ./test.go:9:4: inlining call to F2
    ./test.go:10:4: inlining call to F3
    /var/folders/nr/lxtqsz6x1x1gfbyp1p0jy4p00000gn/T/go-build333003258/b001/_gomod_.go:6:6: can inline init.0
    ./test.go:8:4: main new(S) does not escape
    ./test.go:9:4: main &s does not escape
    ./test.go:14:10: new(S) escapes to heap
    ./test.go:20:9: &s escapes to heap
    ./test.go:19:2: moved to heap: s
    

    If the compiler is smart enough, F1() F2() F3() may not be called. Because it makes no means.

    Don't care about whether a variable is allocated on heap or stack, just use it. Protect it by mutex or channel if necessary.

提交回复
热议问题