此链接:http://research.swtch.com/godata
它说( slice 部分的第三段):
Because slices are multiword structures, not pointers, the slicing operation does not need to allocate memory, not even for the slice header, which can usually be kept on the stack. This representation makes slices about as cheap to use as passing around explicit pointer and length pairs in C. Go originally represented a slice as a pointer to the structure shown above, but doing so meant that every slice operation allocated a new memory object. Even with a fast allocator, that creates a lot of unnecessary work for the garbage collector, and we found that, as was the case with strings above, programs avoided slicing operations in favor of passing explicit indices. Removing the indirection and the allocation made slices cheap enough to avoid passing explicit indices in most cases.
什么……?为什么它不分配任何内存?如果它是多字结构或指针?它不需要分配内存吗?然后它提到它本来是指向那个slice结构的指针,它需要为一个新的对象分配内存。为什么现在不需要这样做?很困惑
最佳答案
the slicing operation does not need to allocate memory.
“slice 操作”指的是 s1[x:y]
之类的东西,而不是 slice 初始化或 make([]int, x)
。例如:
var s1 = []int{0, 1, 2, 3, 4, 5} // <<- allocates (or put on stack)
s2 := s1[1:3] // <<- does not (normally) allocate
也就是说,第二行类似于:
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
…
example := SliceHeader{&s1[1], 2, 5}
通常像 example
这样的局部变量会被放入栈中。就像这样做而不是使用结构一样:
var exampleData uintptr
var exampleLen, exampleCap int
那些 example*
变量进入堆栈。
只有当代码确实 return &example
或 otherFunc(&example)
或以其他方式允许指向 this 的指针转义时,编译器才会被迫在上分配结构(或 slice 头)堆。
Then it mentions that it was originally a pointer to that slice structure, and it needed to allocate memory for a new object. Why does it not need to do that now?
想象一下,您没有执行上述操作:
example2 := &SliceHeader{…same…}
// or
example3 := new(SliceHeader)
example3.Data = …
example3.Len = …
example3.Cap = …
即类型是 *SliceHeader
而不是 SliceHeader
。
根据您提到的内容,这实际上是 slice 过去的样子(Go 1.0 之前)。
它也曾经是 example2
和 example3
都必须在堆上分配。这就是所指的“新对象的内存”。我认为现在逃逸分析将尝试将它们都放入堆栈,只要指针保持在函数的本地,这样它就不再是一个大问题了。不管怎样,避免一级间接寻址是好的,与复制指针并重复取消引用相比,复制三个整数几乎总是更快。
关于pointers - golang 中的 slice 不分配任何内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29196475/