FreeBSD – How FreeBSD Allocates Memory

freebsdkernel

I am aware that this is simplified/generalized explanation, but top(1) utility divides memory in FreeBSD into six pools- Active, Inactive, Wired, Cache, Buffers and Free. Example from top(1) output:

Mem: 130M Active, 42M Inact, 51M Wired, 14M Cache, 34M Buf, 648K Free
Swap: 512M Total, 512M Free

Active is used by running processes and Wired is used mainly for kernel. Inactive is memory from closed processes which is still cached in case it needs to be reused, Cache is cached data, Buffers is disk buffers(I guess it is similar to cached in Linux free(1) output(?)) and Free is completely unused memory. Am I correct that FreeBSD kernel automatically allocates space from Inactive, Cache and Buffers pools to Active or Wired if needed?

Best Answer

To make it short, active and wired is used memory that shouldn't or cannot be swapped out to free memory. While inactive can properly be swapped out, but is still owned (not freed) by a process or the kernel, so this is not heavily used memory, but still used.

New is laundry which is a list of dirty memory pages, which might needs to be written to the swap device. Either if dirty memory needed to be swapped or not, they it is added back into the inactive queue.

Wired memory is not supposed to be swapped, for safety (in case of the kernel) or for userland process optimisation (like ZFS). Wired memory is used for caches of filesystems, which might be freed by the kernel. At lest for ZFS this can be seen as mostly free memory.

Free memory is definitely free.

Cached (now deprecated, I guess) is ready to be freed, since it is already swapped out and only there for possible reallocation.

Buffer is used as a cache by most filesystems (UFS, FAT, ...) and is the amount of memory used by the filesystems. It can be actice, inactive or wired.

ARC (Adaptive Replacement Cache) is the cache used by ZFS and it is memory that can be freed when need.

From the FreeBSD Wiki on Memory

Memory Classes

Active

  • Contains pages "actively" (recently) referenced by userland
  • Contains a mix of clean and dirty pages
  • Pages are regularly scanned by the page daemon (each page is visited once every vm.pageout_update_period seconds)
  • Scans check to see if the page has been referenced since the last scan
  • If enough scans complete without seeing a reference, the page is moved to the inactive queue
  • Implements pseudo-LRU

Inactive

  • Contains pages aged out of the active queue
  • Contains pages evicted from the buffer cache
  • Contains a mix of clean and dirty pages
  • Pages are scanned by the page daemon (starting from the head of the queue) when there is a memory shortage:
    • Pages which have been referenced are moved back to the active queue or the tail of the inactive queue
    • Pages which are dirty are moved to the tail of the laundry queue
    • Unreferenced, clean pages may be freed and reused immediately
  • Implements second-chance LRU

Laundry

  • Queue for managing dirty inactive pages, which must be cleaned ("laundered") before they can be reused
  • Managed by a separate thread, the laundry thread, instead of the page daemon
  • Laundry thread launders a small number of pages to balance the inactive and laundry queues
  • Frequency of laundering depends on:
    • How many clean pages the page daemon is freeing; more frees contributes to a higher frequency of laundering
    • The size of the laundry queue relative to the inactive queue; if the laundry queue is growing, we will launder more frequently
  • Pages are scanned by the laundry thread (starting from the head of the queue):
    • Pages which have been referenced are moved back to the active queue or the tail of the laundry queue
    • Dirty pages are laundered and then moved close to the head of the inactive queue

Free

  • Memory available for use by the rest of the system.

Wired

  • Non-pageable memory: cannot be freed until explicitly released by the owner
  • Userland memory can be wired by mlock(2) (subject to system and per-user limits)
  • Kernel memory allocators return wired memory
  • Contents of the ARC and the buffer cache are wired
  • Some memory is permanently wired and is never freed (e.g., the kernel file itself)

From The design and implementation of the FreeBSD operating system chapter 6.12 Page Replacement (Not fully accurate any more, but here for referenz of the old question):

The kernel divides the main memory into five lists:

  1. Wired: Wired pages are locked in memory and cannot be paged out. Typically these pages are being used by the kernel or the physical-memory pager, or they have been locked down with mlock. In addition, all the pages being used to hold the thread stacks of loaded (i.e. not swapped-out) processes are also wired.
  2. Active: Active pages are being used by one or more regions of virtual memory. Although the kernel can page them out, doing so is likely to cause an active process to fault them back again.
  3. Inactive: Inactive pages may be dirty and have contents that are still known, but they are not usually part of any active region. If the contents of the page are dirty, the contents must be written to backing store before the page can be reused. Once the page has been cleaned, it is moved to the cache list. If the system becomes short of memory, the pageout daemon may try to move active pages to the inactive list in the hopes of finding pages that are not really in use. The selection criteria that are used by the pageout daemon to select pages to move from the active list to the inactive list are described later in this section. When the free-memory and cache lists drop to low, pageout daemon traverses the inactive list to create more cache and free pages.
  4. Cache: Cache pages have contents that are still known, but they are not part of an mapping. If they are faulted into active region, they are not part of any mapping. If they are faulted int an active region, they will be moved from the cache list to the active list. If they are used for a read or a write, they will be moved from the cache list first to the buffer cache and eventually released to the inactive list. An mlock system call can reclaim a page from the cache list and wire it. Pages on the cache list are similar to inactive pages except that they are not dirty, either because they are unmodified since they were paged in or because they have been written to their backing store. They can be claimed for a new use when a page is needed.
  5. Free: Free pages have no useful contents and will be used to fulfill new pagefault requests.

To answer your original question

Am I correct that FreeBSD kernel automatically allocates space from Inactive, Cache and Buffers pools to Active or Wired if needed?

Active pages can become inactive if they were not used for some time. If the kernel swaps out an inactive page this page is moved to the cache list. Page in the cache list are not part of the virtual mapping of any process but can easily be reclaimed, as active or wired. Or when needed for I/O as a buffer cache.

Wired memory can not be swaped out of main memory. If it is wired by a process it needs to be unwired with the munlock call to become active memory again.

Active, inactive and wired memory can be freed by the process or kernel and added to the free list.

Related Question