简短答案
它正在舍入切片容量以填充分配的内存块。
长答案
让我们看一下Go1.5.1源代码:
https://github.com/golang/go/blob/f2e4c8b5fb3660d793b2c545ef207153db0a34b1/src/cmd/compile/internal/gc/walk.go#L2895告诉我们,
append(l1,l2...)扩展为
s := l1if n := len(l1) + len(l2) - cap(s); n > 0 { s = growslice_n(s, n)}s = s[:len(l1)+len(l2)]memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))我们感兴趣的部分在
growslice_n此处定义:https
:
//github.com/golang/go/blob/f2e4c8b5fb3660d793b2c545ef207153db0a34b1/src/runtime/slice.go#L36
再深入一点,我们发现:
newcap := old.capif newcap+newcap < cap { newcap = cap} else { for { if old.len < 1024 { newcap += newcap } else { newcap += newcap / 4 } if newcap >= cap { break } }}capmem := roundupsize(uintptr(newcap) * uintptr(et.size))newcap = int(capmem / uintptr(et.size))roundupsize在此处定义:https
:
//github.com/golang/go/blob/f2e4c8b5fb3660d793b2c545ef207153db0a34b1/src/runtime/msize.go#L178
// Returns size of the memory block that mallocgc will allocate if you ask for the size.func roundupsize(size uintptr) uintptr { if size < _MaxSmallSize { if size <= 1024-8 { return uintptr(class_to_size[size_to_class8[(size+7)>>3]]) } else { return uintptr(class_to_size[size_to_class128[(size-1024+127)>>7]]) } } if size+_PageSize < size { return size } return round(size, _PageSize)}它是在那里介绍的:https : //groups.google.com/forum/#!topic/golang-
prereviews/bFGtI4Cpb_M
当切片增加时,请考虑分配的内存块的大小。



