# Freeable memory on FreeBSD 12+ (I know)



## bgdnlp (Nov 4, 2021)

TL;DR: I need to put "free memory %" on a dashboard. It doesn't have to be perfect. There is no swap. I want to validate my understanding. Is INACTIVE + FREE close enough?

I know that it's not that simple. Knowing that and explaining it to non-technical people who don't care are different things. Also, they are right.

Use case is simple at least. There's a dashboard people look at and the dashboard needs a gauge/graph letting people know if the machine needs more memory. This is on AWS, the machines have no swap. I understand that free is bad, inactive is good. My question is, in most cases, *how much memory can a userland process on the machine request at once* (or in quick succession) before it gets itself or others into trouble with the reaper? Like a PHP or NodeJS script. And the reason why I ask here is that I've seen recommendations of other formulas that seem wrong to me.

My understanding is:
*Active* - can't be freed, userland processes need it.
*Wired* - can't be freed, kernel needs it.
*Laundry* - can't be freed right away. This is the purgatory of memory pages, they need to be sorted out first.
*Inactive* - will be freed any time it's needed.
*Free* - can't get more free than this.
_Buffers/ARC_ - not a real class, part of Wired. Ignore.
_Cache_ - doesn't exist, though it's still reported by some tools. Ignore.

The fact that these machines have no swap makes the wiki entry a bit confusing. 

What happens when the memory is needed but there is no swap to go to? Frees some memory from inactive, right? What about Laundry, does it have a purpose without swap?


----------



## eternal_noob (Nov 4, 2021)

bgdnlp said:


> What happens when the memory is needed but there is no swap to go to?


If there is no more memory left to be freed, the oom killler kicks in and kills random processes.




__





						Preventing FreeBSD to kill PostgreSQL (aka OOM Killer prevention)
					

Something that can be useful when running PostgreSQL on FreeBSD.



					fluca1978.github.io


----------



## a6h (Nov 4, 2021)

To answer a fraction of these parts of your question:


bgdnlp said:


> how much memory can a userland process on the machine request at once





bgdnlp said:


> What happens when the memory is needed but there is no swap to go to? Frees some memory from inactive, right? What about Laundry, does it have a purpose without swap?



It is a complicated subject. To understand it, you have to know how the process management and virtual memory in an OS works. I will try to explain *a very tiny* part of it, in a short summary:

*When system starts:*
1. The kernel checks the physical memory.
2. The kernel determines how many pages are available.
3. Some of them are going to be dedicated to the kernel.
4. The rest of the pages will be described by vm_page structures.
5. vm_page structures will be placed on the _free memory list_.

*What is the vm_page?*
VM represents the physical memory, through the vm_page data structure.

*Process and the address space:*
The header of a process dictates how to initialise the virtual memory.

A process needs space from the VM for four things/area:

1. Program text
* The code.
* It's demand paged.
* It is read-only and executable.

2. Initialized data
* Copy-on-write.

3. Uninitialized data
* Zero-filled page.

4. Stack (run-time)
* Zero-filled page.

A program starts, and the kernel builds the vmspace structure.

*What is the vmspace?*
vmspace is a data structures that will keep track of a process address space, i.e. text, initialized data, uninitialized data and run-time stack.

*What about the shared libraries?*
If a program uses a shared library, the ld-elf.so(1) handles the space allocation (not the kernel).

That is the start-up. After that, the process starts at the main entry.

*Page Fault*
If a process needs more memory, i.e. accessing a non-resident address, then there will be a _page fault_.
When a page fault occurs, kernel will do some calculations on the vmspace data structure. It could lead to two scenarios:

1. An invalid access to the address space, which leads to a segment fault signal.
2. A valid access to the address space:

When page fault happens, i.e. a vm_object is faulted, it allocates a page from the _free memory list_.

*What is the vm_object?*
vm_object is a data structure. It describes a source of data or instruction on the physical memory, for example.

*When memory is low:*
The paging daemon will do some math, finds unactive unused pages, saves the modified contents, removes mappings and will add them to the _free memory list_.

*Running out of VM:*
The VM is limited to the available "physical memory" + "swap". The kernel does not give more VM than, what it can provide.

When a page fault happens, and there is no more memory available (running out of VM),
i.e. there is no more pages -- beside some reserved ones, then:
the kernel will send "kill signal" to the page faulting process.

*The protect utility*
When there's no more swap, protect(1) can be used to prevent a process get killed by the kernel. It uses the procctl(2) syscall.


----------



## mer (Nov 4, 2021)

Buffers/ARC:  they are part of Wired, but they act differently.  ARC for ZFS is flexible.  It's cache (basically READ cache) which means the data in ARC is backed by data on the physical devices.  Like all caches, you flush them and all you do is take a performance hit.  ARC by design has high and low limits.  If ARC is at/near it's high limit and the rest of system memory is in use, ARC will start flushing so the kernel can reclaim memory.  It's not instantaneous, it may take a second or 5, but ARC by design can be reclaimed.  One can also limit it's growth (not desirable on servers, my opinion desirable on desktops so opening new tabs in Firefox doesn't cause OOM issues).  So ARC may be counted as Wired, but it's really "Wired that can be reclaimed easily but not quickly".

Buffers, at least for disk devices, are similar to ARC in that they are reclaimed when not needed (data written to disk, etc).
Buffers may also cover buffers needed for the network stack (mbufs and others).  There is usually a minium, it can grow as needed, there is likely a max value.

Specifically for your question (my opinion):
Free is free/not in use.
When a program exits, any memory in use by it should get freed, it may not be instaneous, so the memory may wind up on the Inactive/Laundry lists, some percentage of those may actually be available for reclaimation, but not currently free, reclaiming would be slowpath.
ARC/Buffers: in use but can be reclaimed if needed on a slowpath.

In your case I would simply report the Free value.  It's least confusing to explain, it's conservative, swap/no swap doesn't matter.


----------

