我知道(并在互联网上阅读 - 包括此资源(。增加内存的逻辑是:如果 len 数组小于 1024 - golang 乘以数组 2 否则乘以 len 在 1.25 上(我们在源代码中看到了这一点毫无疑问 https://github.com/golang/go/blob/cb2353deb74ecc1ca2105be44881c5d563a00fb8/src/runtime/slice.go#L95( 但是如果我在循环中填充切片,我会看到这种行为
t := []int{}
z := 0
for i := 1; i < 10000; i++ {
t = append(t, i)
if z < cap(t) {
z = cap(t)
fmt.Println(" len - ", len(t), " : cap - ", cap(t))
}
}
伦又名 NUM
len - 1 : cap - 1
len - 2 : cap - 2
len - 3 : cap - 4
len - 5 : cap - 8
len - 9 : cap - 16
len - 17 : cap - 32
len - 33 : cap - 64
len - 65 : cap - 128
len - 129 : cap - 256
len - 257 : cap - 512
len - 513 : cap - 1024
len - 1025 : cap - 1280
len - 1281 : cap - 1696
len - 1697 : cap - 2304
len - 2305 : cap - 3072
len - 3073 : cap - 4096
len - 4097 : cap - 5120
len - 5121 : cap - 7168
len - 7169 : cap - 9216
len - 9217 : cap - 12288
before len 513 - capacity grow x2
len 1025 = 1.25 * len 513 = 1280 - capacity grow x1.25 (ok)
next capacity 1280*1.25 = 1600, but i see 1696 (len 1281).
Why difference = 96?
len 1281 - 3073 wrong, but len 3073 * 1.25 = 5120 (len 4097)
如果 golang 可以在增加切片时增加容量阵列,那么当所指的切片太小时,它能减少阵列吗?
谢谢!
下一个容量 1280*1.25 = 1600,但我看到 1696 (len 1281(。
src/runtime/malloc.go
// Small allocation sizes (up to and including 32 kB) are // rounded to one of about 70 size classes, each of which // has its own free set of objects of exactly that size.
growslice
请求最小分配大小。mallocgc
执行分配。mallocgc
向上舍入到班级规模,以最大程度地减少碎片。
编写收缩内存函数。
package main
import "fmt"
func shrink(s []byte) []byte {
if (cap(s)-len(s))/len(s) >= 1 {
t := s
s = make([]byte, len(s), 2*len(s))
copy(s, t)
}
return s
}
func main() {
s := make([]byte, 32, 256)
fmt.Println(len(s), cap(s))
s = shrink(s)
fmt.Println(len(s), cap(s))
}
游乐场:https://play.golang.org/p/udAEBJ-kWQ9
输出:
32 256
32 64
如您所见,这需要时间和内存。只有您可以决定在您的特定情况下是否值得。