Skip to content

runtime: heap pageAlloc.searchAddr strategy may be wrong #41989

@dreamerjackson

Description

@dreamerjackson

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
	}

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions