Skip to content

Instantly share code, notes, and snippets.

@nevill
Last active February 15, 2020 16:36
Show Gist options
  • Save nevill/930c003cfe10d84d2c5d071b804f8343 to your computer and use it in GitHub Desktop.
Save nevill/930c003cfe10d84d2c5d071b804f8343 to your computer and use it in GitHub Desktop.
Go Memory Allocation

Allocator

Data structures

  • fixalloc
    • a free-list allocator for fixed-size off-heap objects, used to manage storage used by the allocator.
  • mheap
    • the malloc heap, managed at page (8192-byte) granularity.
  • mspan
    • a run of pages managed by the mheap.
  • mcentral
    • collects all spans of a given size class.
  • mcache
    • a per-P cache of mspans with free space.
  • mstats
    • allocation statistics

OS memory

Regions of the address space managed by the runtime may be in one of four states at any given time:

  1. None - Unreserved and unmapped, the default state of any region.
  2. Reserved - Owned by the runtime, but accessing it would cause a fault. Does not count against the process's memory footprint.
  3. Prepared - Reserved, intended not to be backed by physical memory (though an OS may implement this lazily). Can transition efficiently to Ready. Accessing memory in such a region is undefined (may fault, may give back unexpected zeroes, etc.).
  4. Ready - may be accessed safely.

Corresponding sys calls

  • sysAlloc transitions an OS-chosen region of memory from None to Ready.
  • sysFree transitions a memory region from any state to None
  • sysReserve transitions a memory region from None to Reserved.
  • sysMap transitions a memory region from Reserved to Prepared.
  • sysUsed transitions a memory region from Prepared to Ready. This is usually a no-op.
  • sysUnused transitions a memory region from Ready to Prepared.
  • sysFault transitions a memory region from Ready or Prepared to Reserved. Used only for debugging the runtime.

Memstats

  • An "idle" span contains no objects or other data. The physical memory backing an idle span can be released back to the OS (but the virtual address space never is), or it can be converted into an "in use" or "stack" span.
  • An "in use" span contains at least one heap object and may have free space available to allocate more heap objects.
  • A "stack" span is used for goroutine stacks. Stack spans are not considered part of the heap. A span can change between heap and stack memory; it is never used for both simultaneously.

Evictable vs non evictable

inuse = alloc + fragmentation
idle = released + amount could be returned

HeapAlloc

  • "Allocated" heap objects include all reachable objects, as well as unreachable objects that the garbage collector has not yet freed. Specifically, HeapAlloc increases as heap objects are allocated and decreases as the heap is swept and unreachable objects are freed.

HeapSys

  • HeapSys measures the amount of virtual address space reserved for the heap. This includes virtual address space that has been reserved but not yet used, which consumes no physical memory, but tends to be small, as well as virtual address space for which the physical memory has been returned to the OS after it became unused.

HeapIdle

  • Idle spans have no objects in them. These spans could be (and may already have been) returned to the OS, or they can be reused for heap allocations, or they can be reused as stack memory. HeapIdle minus HeapReleased estimates the amount of memory that could be returned to the OS, but is being retained by the runtime so it can grow the heap without requesting more memory from the OS. If this difference is significantly larger than the heap size, it indicates there was a recent transient spike in live heap size.

HeapInuse

  • In-use spans have at least one object in them. These spans can only be used for other objects of roughly the same size. HeapInuse minus HeapAlloc estimates the amount of memory that has been dedicated to particular size classes, but is not currently being used. This is an upper bound on fragmentation, but in general this memory can be reused efficiently.

HeapReleased

  • HeapReleased is bytes of physical memory returned to the OS. This counts heap memory from idle spans that was returned to the OS and has not yet been reacquired for the heap.

Reference

  1. malloc.go
  2. mheap.go
  3. mem_linux.go
  4. mstats.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment