#!/bin/sh
# Retrieve required sysctl values
hw_physmem=$(sysctl -n hw.physmem)
pagesize=$(sysctl -n hw.pagesize)
v_page_count=$(sysctl -n vm.stats.vm.v_page_count)
v_wire_count=$(sysctl -n vm.stats.vm.v_wire_count)
v_active_count=$(sysctl -n vm.stats.vm.v_active_count)
v_inactive_count=$(sysctl -n vm.stats.vm.v_inactive_count)
v_cache_count=$(sysctl -n vm.stats.vm.v_cache_count)
v_free_count=$(sysctl -n vm.stats.vm.v_free_count)
v_laundry_count=$(sysctl -n vm.stats.vm.v_laundry_count)
zfs_arc=$(sysctl -n kstat.zfs.misc.arcstats.size)
zfs_arc_min=$(sysctl -n kstat.zfs.misc.arcstats.c_min)
zfs_arc_max=$(sysctl -n kstat.zfs.misc.arcstats.c_max)
mem_buf=$(sysctl -n vfs.bufspace)
# Calculate values in bytes
mem_phys=$hw_physmem
mem_all=$((v_page_count * pagesize))
mem_wire=$((v_wire_count * pagesize))
mem_active=$((v_active_count * pagesize))
mem_inactive=$((v_inactive_count * pagesize))
mem_cache=$((v_cache_count * pagesize))
mem_free=$((v_free_count * pagesize))
mem_laundry=$((v_laundry_count * pagesize))
# Round up to next reasonable power-of-two based on assumed 8 memory modules
mem_rounded() {
size=$1
chip_guess=$(( (size / 8) - 1 ))
chip_size=1
while [ "$chip_guess" -gt 0 ]; do
chip_guess=$(( chip_guess >> 1 ))
chip_size=$(( chip_size << 1 ))
done
echo $(( ((size + chip_size - 1) / chip_size) * chip_size ))
}
mem_hw=$(mem_rounded "$mem_phys")
# Gaps
mem_gap_vm=$((mem_all - (mem_wire + mem_active + mem_inactive + mem_cache + mem_free + mem_laundry)))
mem_gap_sys=$((mem_phys - mem_all))
mem_gap_hw=$((mem_hw - mem_phys))
# Logical memory
mem_total=$mem_hw
mem_avail=$((mem_inactive + mem_cache + mem_free + mem_buf))
mem_avail_total=$((mem_avail + zfs_arc - zfc_arc_min))
mem_used=$((mem_total - mem_avail))
# Print results
print_line() {
label=$1
symbol=$2
bytes=$3
desc=$4
percent=$5
mb=$((bytes / (1024 * 1024)))
printf "%-15s%s %12d (%7dMB) " "$label:" "$symbol" "$bytes" "$mb"
if [ -n "$percent" ]; then
printf "[%3d%%] " "$percent"
else
printf " "
fi
echo "$desc"
}
percent() {
awk "BEGIN { printf \"%d\", ($1 / $2) * 100 }"
}
HR="---------------- ------------ ----------- ------"
echo "SYSTEM MEMORY INFORMATION:"
print_line "mem_wire" " " "$mem_wire" "Wired: disabled for paging out" "$(percent $mem_wire $mem_all)"
print_line "mem_active" "+" "$mem_active" "Active: recently referenced" "$(percent $mem_active $mem_all)"
print_line "mem_inactive" "+" "$mem_inactive" "Inactive: recently not referenced" "$(percent $mem_inactive $mem_all)"
print_line "mem_cache" "+" "$mem_cache" "Cached: almost avail. for allocation" "$(percent $mem_cache $mem_all)"
print_line "mem_buf" "+" "$mem_buf" "UFS buffer cache: almost avail. for allocation" "$(percent $mem_buf $mem_all)"
print_line "mem_free" "+" "$mem_free" "Free: fully available for allocation" "$(percent $mem_free $mem_all)"
print_line "mem_laundry" "+" "$mem_laundry" "Laundered: must be cleaned before re-allocation" "$(percent $mem_laundry $mem_all)"
print_line "mem_gap_vm" "+" "$mem_gap_vm" "Memory gap: UNKNOWN" "$(percent $mem_gap_vm $mem_all)"
echo "$HR"
print_line "mem_all" "=" "$mem_all" "Total real memory managed" 100
print_line "mem_gap_sys" "+" "$mem_gap_sys" "Memory gap: Kernel?!"
echo "$HR"
print_line "mem_phys" "=" "$mem_phys" "Total real memory available"
print_line "mem_gap_hw" "+" "$mem_gap_hw" "Memory gap: Probably BIOS + iGPU VRAM (?)"
echo "$HR"
print_line "mem_hw" "=" "$mem_hw" "Total real memory installed"
echo "$HR"
echo
echo "SYSTEM MEMORY SUMMARY:"
print_line "mem_used" " " "$mem_used" "Logically used memory" "$(percent $mem_used $mem_total)"
print_line "mem_avail_cur" "=" "$mem_avail" "Logically available memory" "$(percent $mem_avail $mem_total)"
print_line "mem_avail_max" "=" "$mem_avail_total" "Maximum available memory" "$(percent $mem_avail_total $mem_total)"
echo "$HR"
print_line "mem_total" "+" "$mem_total" "Logically total memory" 100
echo "$HR"
echo
echo "EXTRA INFO:"
print_line "zfs_arc" "=" "$zfs_arc" "ZFS Adaptive Replacement Cache (part of mem_wire)" "$(percent $zfs_arc $mem_all)"
print_line "zfs_arc_min" "=" "$zfs_arc_min" "Minimum amount of ZFS ARC" "$(percent $zfs_arc_min $mem_all)"
print_line "zfs_arc_max" "=" "$zfs_arc_max" "Maximum amount of ZFS ARC" "$(percent $zfs_arc_max $mem_all)"
echo "$HR"