diff options
-rw-r--r-- | unix/freebsd-memory.pl | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/unix/freebsd-memory.pl b/unix/freebsd-memory.pl new file mode 100644 index 0000000..61e7936 --- /dev/null +++ b/unix/freebsd-memory.pl @@ -0,0 +1,120 @@ +#!/usr/bin/env perl +## +## freebsd-memory -- List Total System Memory Usage +## Copyright (c) 2003-2004 Ralf S. Engelschall <rse@engelschall.com> +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions +## are met: +## 1. Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## 2. Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +## SUCH DAMAGE. +## + +# query the system through the generic sysctl(8) interface +# (this does not require special priviledges) +my $sysctl = {}; +my $sysctl_output = `/sbin/sysctl -a`; +foreach my $line (split(/\n/, $sysctl_output)) { + if ($line =~ m/^([^:]+):\s+(.+)\s*$/s) { + $sysctl->{$1} = $2; + } +} + +# round the physical memory size to the next power of two which is +# reasonable for memory cards. We do this by first determining the +# guessed memory card size under the assumption that usual computer +# hardware has an average of a maximally eight memory cards installed +# and those are usually of equal size. +sub mem_rounded { + my ($mem_size) = @_; + my $chip_size = 1; + my $chip_guess = ($mem_size / 8) - 1; + while ($chip_guess != 0) { + $chip_guess >>= 1; + $chip_size <<= 1; + } + my $mem_round = (int($mem_size / $chip_size) + 1) * $chip_size; + return $mem_round; +} + +# determine the individual known information +# NOTICE: forget hw.usermem, it is just (hw.physmem - vm.stats.vm.v_wire_count). +# NOTICE: forget vm.stats.misc.zero_page_count, it is just the subset of +# vm.stats.vm.v_free_count which is already pre-zeroed. +my $mem_hw = &mem_rounded($sysctl->{"hw.physmem"}); +my $mem_phys = $sysctl->{"hw.physmem"}; +my $mem_all = $sysctl->{"vm.stats.vm.v_page_count"} * $sysctl->{"hw.pagesize"}; +my $mem_wire = $sysctl->{"vm.stats.vm.v_wire_count"} * $sysctl->{"hw.pagesize"}; +my $mem_active = $sysctl->{"vm.stats.vm.v_active_count"} * $sysctl->{"hw.pagesize"}; +my $mem_inactive = $sysctl->{"vm.stats.vm.v_inactive_count"} * $sysctl->{"hw.pagesize"}; +my $mem_cache = $sysctl->{"vm.stats.vm.v_cache_count"} * $sysctl->{"hw.pagesize"}; +my $mem_free = $sysctl->{"vm.stats.vm.v_free_count"} * $sysctl->{"hw.pagesize"}; + +# determine the individual unknown information +my $mem_gap_vm = $mem_all - ($mem_wire + $mem_active + $mem_inactive + $mem_cache + $mem_free); +my $mem_gap_sys = $mem_phys - $mem_all; +my $mem_gap_hw = $mem_hw - $mem_phys; + +# determine logical summary information +my $mem_total = $mem_hw; +my $mem_avail = $mem_inactive + $mem_cache + $mem_free; +my $mem_used = $mem_total - $mem_avail; + +# information annotations +my $info = { + "mem_wire" => 'Wired: disabled for paging out', + "mem_active" => 'Active: recently referenced', + "mem_inactive" => 'Inactive: recently not referenced', + "mem_cache" => 'Cached: almost avail. for allocation', + "mem_free" => 'Free: fully available for allocation', + "mem_gap_vm" => 'Memory gap: UNKNOWN', + "mem_all" => 'Total real memory managed', + "mem_gap_sys" => 'Memory gap: Kernel?!', + "mem_phys" => 'Total real memory available', + "mem_gap_hw" => 'Memory gap: Segment Mappings?!', + "mem_hw" => 'Total real memory installed', + "mem_used" => 'Logically used memory', + "mem_avail" => 'Logically available memory', + "mem_total" => 'Logically total memory', +}; + +# print system results +printf("SYSTEM MEMORY INFORMATION:\n"); +printf("mem_wire: %12d (%7dMB) [%3d%%] %s\n", $mem_wire, $mem_wire / (1024*1024), ($mem_wire / $mem_all) * 100, $info->{"mem_wire"}); +printf("mem_active: + %12d (%7dMB) [%3d%%] %s\n", $mem_active, $mem_active / (1024*1024), ($mem_active / $mem_all) * 100, $info->{"mem_active"}); +printf("mem_inactive:+ %12d (%7dMB) [%3d%%] %s\n", $mem_inactive, $mem_inactive / (1024*1024), ($mem_inactive / $mem_all) * 100, $info->{"mem_inactive"}); +printf("mem_cache: + %12d (%7dMB) [%3d%%] %s\n", $mem_cache, $mem_cache / (1024*1024), ($mem_cache / $mem_all) * 100, $info->{"mem_cache"}); +printf("mem_free: + %12d (%7dMB) [%3d%%] %s\n", $mem_free, $mem_free / (1024*1024), ($mem_free / $mem_all) * 100, $info->{"mem_free"}); +printf("mem_gap_vm: + %12d (%7dMB) [%3d%%] %s\n", $mem_gap_vm, $mem_gap_vm / (1024*1024), ($mem_gap_vm / $mem_all) * 100, $info->{"mem_gap_vm"}); +printf("-------------- ------------ ----------- ------\n"); +printf("mem_all: = %12d (%7dMB) [100%%] %s\n", $mem_all, $mem_all / (1024*1024), $info->{"mem_all"}); +printf("mem_gap_sys: + %12d (%7dMB) %s\n", $mem_gap_sys, $mem_gap_sys / (1024*1024), $info->{"mem_gap_sys"}); +printf("-------------- ------------ -----------\n"); +printf("mem_phys: = %12d (%7dMB) %s\n", $mem_phys, $mem_phys / (1024*1024), $info->{"mem_phys"}); +printf("mem_gap_hw: + %12d (%7dMB) %s\n", $mem_gap_hw, $mem_gap_hw / (1024*1024), $info->{"mem_gap_hw"}); +printf("-------------- ------------ -----------\n"); +printf("mem_hw: = %12d (%7dMB) %s\n", $mem_hw, $mem_hw / (1024*1024), $info->{"mem_hw"}); + +# print logical results +printf("\n"); +printf("SYSTEM MEMORY SUMMARY:\n"); +printf("mem_used: %12d (%7dMB) [%3d%%] %s\n", $mem_used, $mem_used / (1024*1024), ($mem_used / $mem_total) * 100, $info->{"mem_used"}); +printf("mem_avail: + %12d (%7dMB) [%3d%%] %s\n", $mem_avail, $mem_avail / (1024*1024), ($mem_avail / $mem_total) * 100, $info->{"mem_avail"}); +printf("-------------- ------------ ----------- ------\n"); +printf("mem_total: = %12d (%7dMB) [100%%] %s\n", $mem_total, $mem_total / (1024*1024), $info->{"mem_total"}); + |