什么被认为是;“小”;关于堆栈分配的Go中的对象?

什么被认为是;“小”;关于堆栈分配的Go中的对象?,go,slice,allocation,escape-analysis,Go,Slice,Allocation,Escape Analysis,守则: func MaxSmallSize() { a := make([]int64, 8191) b := make([]int64, 8192) _ = a _ = b } 然后运行go build-gcflags='-m'。2> &1检查内存分配详细信息。结果是: ./mem.go:10: can inline MaxSmallSize ./mem.go:12: make([]int64, 8192) escapes to heap ./mem.go:1

守则:

func MaxSmallSize() {
    a := make([]int64, 8191)
    b := make([]int64, 8192)
    _ = a
    _ = b
}
然后运行
go build-gcflags='-m'。2> &1
检查内存分配详细信息。结果是:

./mem.go:10: can inline MaxSmallSize
./mem.go:12: make([]int64, 8192) escapes to heap
./mem.go:11: MaxSmallSize make([]int64, 8191) does not escape
我的问题是为什么
a
是小对象而
b
是大对象?


make
64KB将转义到堆中,更少的内存将分配到堆栈中。
\u maxsallsize=32由于语言规范中没有提到这一点,它是一个实现细节,因此,它可能会根据许多情况(Go版本、目标操作系统、体系结构等)而有所不同

如果您想找到它的当前值或开始挖掘的位置,请查看
cmd/compile/internal/gc

决定在何处分配变量的。在未报告的函数中检查生成切片操作
esc()

尺寸限制如下:

r.Int64() < (1<<16)/t.Elem().Width
就你而言:

NumElem < 65536 / 8 = 8192
NumElem<65536/8=8192

因此,如果切片类型是
[]uint64
,8192是在堆(而不是堆栈)上分配的限制,正如您所经历的那样。

这取决于实现,不同的编译器可能会以不同的方式执行,不同的体系结构可能会以不同的方式执行,不同的版本可能会以不同的方式处理。那么你的问题到底是什么?
func isSmallMakeSlice(n *Node) bool {
    if n.Op != OMAKESLICE {
        return false
    }
    l := n.Left
    r := n.Right
    if r == nil {
        r = l
    }
    t := n.Type

    return Smallintconst(l) && Smallintconst(r) && (t.Elem().Width == 0 || r.Int64() < (1<<16)/t.Elem().Width)
}
r.Int64() < (1<<16)/t.Elem().Width
NumElem < 65536 / SizeElem
NumElem < 65536 / 8 = 8192