Freemem.pl


#!/usr/bin/perl

#   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%%] %sn", $mem_wire,     $mem_wire     / (1024*1024), ($mem_wire     / $mem_all) * 100, $info->{"mem_wire"});
printf("mem_active:  + %12d (%7dMB) [%3d%%] %sn", $mem_active,   $mem_active   / (1024*1024), ($mem_active   / $mem_all) * 100, $info->{"mem_active"});
printf("mem_inactive:+ %12d (%7dMB) [%3d%%] %sn", $mem_inactive, $mem_inactive / (1024*1024), ($mem_inactive / $mem_all) * 100, $info->{"mem_inactive"});
printf("mem_cache:   + %12d (%7dMB) [%3d%%] %sn", $mem_cache,    $mem_cache    / (1024*1024), ($mem_cache    / $mem_all) * 100, $info->{"mem_cache"});
printf("mem_free:    + %12d (%7dMB) [%3d%%] %sn", $mem_free,     $mem_free     / (1024*1024), ($mem_free     / $mem_all) * 100, $info->{"mem_free"});
printf("mem_gap_vm:  + %12d (%7dMB) [%3d%%] %sn", $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%%] %sn", $mem_all,      $mem_all      / (1024*1024), $info->{"mem_all"});
printf("mem_gap_sys: + %12d (%7dMB)        %sn",  $mem_gap_sys,  $mem_gap_sys  / (1024*1024), $info->{"mem_gap_sys"});
printf("-------------- ------------ -----------n");
printf("mem_phys:    = %12d (%7dMB)        %sn",  $mem_phys,     $mem_phys     / (1024*1024), $info->{"mem_phys"});
printf("mem_gap_hw:  + %12d (%7dMB)        %sn",  $mem_gap_hw,   $mem_gap_hw   / (1024*1024), $info->{"mem_gap_hw"});
printf("-------------- ------------ -----------n");
printf("mem_hw:      = %12d (%7dMB)        %sn",  $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%%] %sn", $mem_used,  $mem_used  / (1024*1024), ($mem_used  / $mem_total) * 100, $info->{"mem_used"});
printf("mem_avail:   + %12d (%7dMB) [%3d%%] %sn", $mem_avail, $mem_avail / (1024*1024), ($mem_avail / $mem_total) * 100, $info->{"mem_avail"});
printf("-------------- ------------ ----------- ------n");
printf("mem_total:   = %12d (%7dMB) [100%%] %sn", $mem_total, $mem_total / (1024*1024), $info->{"mem_total"});