1.内存块span的sizeclass指的是什么,和page的个数有关系吗
2.从内存分配的角度来说, 一个大对象是至少32K,而一个page默认的是4k 一个大对象就是至少8个page 这样对吗
* 内存块span的sizeclass指的是什么,和page的个数有关系吗
* span通过splanclass标识属于哪种规格的span,golang的span规格一共有67种,具体查看. `src/runtime/sizeclasses.go`
另外,最低位标示是否是一个noscan的span,高7位标示属于哪一种类型,创建一个SpanClass函数如下。每一个span 是跟page数量有关系的。从源码mspan `src/runtime/mheap.go`中也可以看出来
```golang
func makeSpanClass(sizeclass uint8, noscan bool) spanClass {
return spanClass(sizeclass<<1) | spanClass(bool2int(noscan))
}
```
* 从内存分配的角度来说, 一个大对象是至少32K,而一个page默认的是4k 一个大对象就是至少8个page 这样对吗
* golang一个page的大小是:8KB
* 一个大对象至少是page的整数倍,从`go/src/runtime/malloc.go` 中`largeAlloc` 可以看出
```golang
func largeAlloc(size uintptr, needzero bool, noscan bool) *mspan {
// print("largeAlloc size=", size, "\n")
if size+_PageSize < size {
throw("out of memory")
}
//页的整数倍, size >> _PageShift 相当于除8192
npages := size >> _PageShift
if size&_PageMask != 0 {
npages++
}
// Deduct credit for this span allocation and sweep if
// necessary. mHeap_Alloc will also sweep npages, so this only
// pays the debt down to npage pages.
deductSweepCredit(npages*_PageSize, npages)
s := mheap_.alloc(npages, makeSpanClass(0, noscan), needzero)
if s == nil {
throw("out of memory")
}
s.limit = s.base() + size
heapBitsForAddr(s.base()).initSpan(s)
return s
}
```
#1
更多评论
##### 问题1
- sizeclass 代表对象大小的级别,每个级别对象的大小是固定的,共67个级别 0是给大对象用的,其他给小对象用。
- spanclass 对象分为包含指针和不包含指针的,所以spanclass共134个级别。是sizeclass的两倍。一个spanclass中包含了sizeclass和nosan(是否包含指针)
- 不同的span,根据其spanclass,来计算该span需要的page数量,然后按page的数量向页分配器申请指定数量的连续的页,来组成一个span。span会根据其对应spanclass的sizeclass,将span分成一个个对象。同一个span中对象的大小都一样的。
```
npages := uintptr(class_to_allocnpages[c.spanclass.sizeclass()]) // span需要的page数量
size := uintptr(class_to_size[c.spanclass.sizeclass()]) // span中每个对象的大小
```
##### 问题2
- 楼上说的对
#2