-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
i read the heap alloc code. and find the pageAlloc.searchAddr may have a problem, as the comment say
i hope someone can review it @mknyszek
type pageAlloc struct {
// The address to start an allocation search with. It must never
// point to any memory that is not contained in inUse, i.e.
// inUse.contains(searchAddr) must always be true.
//
// When added with arenaBaseOffset, we guarantee that
// all valid heap addresses (when also added with
// arenaBaseOffset) below this value are allocated and
// not worth searching.
//
// Note that adding in arenaBaseOffset transforms addresses
// to a new address space with a linear view of the full address
// space on architectures with segmented address spaces.
searchAddr offAddr
why i think it may have problem? when we find the continue npages in radix tree(code is below), the searchAddr will increase when j++ into new entry in the same level. but it only mean below searchAddr just not enough contiguous space to alloc npages。but it may can alloc mpages(mpages < npages) below searchAddr。 so next time when we want to alloc mpages, we give up the change to alloc mpages which address below searchAddr, so we can't use the heap Efficiently。
and we may alloc more memory because when we can't find mpages we will grow the memory.
func (s *pageAlloc) find(npages uintptr) (uintptr, offAddr) {
for j := j0; j < len(entries); j++ {
..
// We've encountered a non-zero summary which means
// free memory, so update firstFree.
foundFree(levelIndexToOffAddr(l, i+j), (uintptr(1)<<logMaxPages)*pageSize)
....
if size >= uint(npages) {
addr := levelIndexToOffAddr(l, i).add(uintptr(base) * pageSize).addr()
return addr, firstFree.base
}
}
and , the searchAddr can only recover when free npages
func (s *pageAlloc) free(base, npages uintptr) {
// If we're freeing pages below the s.searchAddr, update searchAddr.
if b := (offAddr{base}); b.lessThan(s.searchAddr) {
s.searchAddr = b
}