Freebsd – Reliably determine free memory in BSD

bsdfreebsdmemorytop

Linux distributions tend (but are not required) to include free from procps, which allows a nice concise display of memory consumption:

# free -m
              total        used        free      shared  buff/cache   available
Mem:           7688        5027         180         827        2479        1589
Swap:          8189        2082        6106

In order to approximate this in BSD, I've tried a number of different items, but they all give me different answers (presumably because they have different contexts?). For example:

# sysctl -a |grep Memory
Virtual Memory:             (Total: 1077397132K, Active 3458308K)
Real Memory:                (Total: 1171952K Active 975744K)
Shared Virtual Memory:      (Total: 56264K Active: 38652K)
Shared Real Memory: (Total: 22184K Active: 19700K)
Free Memory Pages:  1664588K

# sysctl hw |awk '/mem:/ { printf "%s %.0fM\n", $1, $2/1024^2 }'
hw.physmem: 32756M
hw.usermem: 29102M
hw.realmem: 33792M

# grep memory /var/run/dmesg.boot
usable memory = 34346901504 (32755 MB)
avail memory  = 33139134464 (31603 MB)

# top |grep -Em2 '^(Mem|Swap):'
Mem: 980M Active, 25G Inact, 3654M Wired, 948M Cache, 3285M Buf, 678M Free
Swap: 9216M Total, 363M Used, 8853M Free, 3% Inuse

I'm not the first person to have this inquiry; almost 7y ago, it was posted to the FreeBSD-questions list and a perl script was proposed out of it, offering freebsd-memory.pl (output was narrowed to fit here):

# perl freebsd-memory.pl
SYSTEM MEMORY INFORMATION:
mem_wire:       3831771136 (  3654MB) [ 11%] Wired: disabled for paging out
mem_active:  +  1028284416 (   980MB) [  3%] Active: recently referenced
mem_inactive:+ 26741092352 ( 25502MB) [ 80%] Inactive: recently not referenced
mem_cache:   +   993902592 (   947MB) [  2%] Cached: almost avail. for allocation
mem_free:    +   710340608 (   677MB) [  2%] Free: fully available for allocation
mem_gap_vm:  +      995328 (     0MB) [  0%] Memory gap: UNKNOWN
-------------- ----------- ---------- ------
mem_all:     = 33306386432 ( 31763MB) [100%] Total real memory managed
mem_gap_sys: +  1040515072 (   992MB)        Memory gap: Kernel?!
-------------- ----------- ----------
mem_phys:    = 34346901504 ( 32755MB)        Total real memory available
mem_gap_hw:  +    12836864 (    12MB)        Memory gap: Segment Mappings?!
-------------- ----------- ----------
mem_hw:      = 34359738368 ( 32768MB)        Total real memory installed

SYSTEM MEMORY SUMMARY:
mem_used:       5914402816 (  5640MB) [ 17%] Logically used memory
mem_avail:   + 28445335552 ( 27127MB) [ 82%] Logically available memory
-------------- ----------- ---------- ------
mem_total:   = 34359738368 ( 32768MB) [100%] Logically total memory

Update from forquare's answer – yet another method:

# vmstat -h
 procs      memory      page                    disks     faults         cpu
 r b w     avm    fre   flt  re  pi  po    fr  sr da0 da1   in   sy   cs us sy id
 0 2 0   3372M  1627M    39  32   0   0     8  23   0   0   23   25   38 19  9 71

# swapinfo -h
Device          1K-blocks     Used    Avail Capacity
/dev/da0s1b       9437184     363M     8.6G     4%

I ran all seven of the above BSD commands (sysctl two ways, /var/run/dmesg.boot, top, freebsd-memory.pl, vmstat, swapinfo) on a single command line, so the output should be pretty consistent, yet I see a lot of conflicting values.

Which of these is "most accurate?" I want a small script (no compilation!) that can be run on pretty much any system (or else just BSD) that concisely display my memory consumption the way procps free does.

I'm using top |grep -Em2 '^(Mem|Swap):' at the moment.

 

Side note 1: Freecolor is almost exactly what I want, but it require compilation and it has a dependency that I don't want to deal with (I'm not the maintainer of these systems), but it may help visitors looking at this question.

Side note 2: The procps (Linux) top command doesn't play well with pipes. You can make it faster with top -d.1 -n1, but it might make your cursor vanish.

Best Answer

For simple free/active figures, I've always used vmstat:

~ # vmstat
procs  memory       page                    disks     faults         cpu
r b w  avm   fre   flt  re  pi  po    fr   sr da0 cd0   in    sy    cs us sy id
1 0 2 841M   89M    23   0   0   0    29    9   0   0    4   110    93  0  0 100

From the man page:

Information about the usage of virtual and real memory. Virtual pages (reported in units of 1024 bytes) are considered active if they belong to processes which are running or have run in the last 20 seconds.

         avm     active virtual pages
         fre     size of the free list

For information on swap usage:

~ # swapinfo -h
Device          1K-blocks     Used    Avail Capacity
/dev/da0p2        2097152      25M     2.0G     1%
Related Question