os_mon memsup reporting memory consumption

Serge Aleynikov <>
Tue Aug 29 19:27:00 CEST 2006


We had a few high memory watermark alarms in a production system running 
Linux reported by OS_MON whereas it seemed like the memory utilization 
on the server wasn't bad.  I looked at the implementation of the 
memsup.erl module in OS_MON, and I believe the calculation of allocated 
memory has a flow.

Memsup's code (sited at the end) reveals that allocated memory doesn't 
take in consideration cached memory.  Since cached memory can be quickly 
freed by the Linux memory manager if additional memory is needed by 
applications, it looks to me that it should be:

Allocated = MemFree + Cached

or even:

Allocated = MemFree + Buffers + Cached

This would be consistent with what "free" is showing on the "-/+ 
buffers/cache" line:

: ~$ uname -a
Linux drpdb02.corp.idt.net 2.6.9-5.ELsmp #1 SMP Wed Jan 5 19:30:39 EST 
2005 i686 i686 i386 GNU/Linux

: ~$ free
              total      used       free     shared    buffers     cached
Mem:       4150324   3416788     733536          0     282412    2621788
-/+ buffers/cache:    512588    3637736
Swap:      2048248         0    2048248

: ~$ head -4 /proc/meminfo
MemTotal:      4150324 kB
MemFree:        733536 kB
Buffers:        282412 kB
Cached:        2621788 kB



%-------------------------
%% @spec get_memory_usage_linux() -> {Allocated, Total}
%-------------------------
get_memory_usage_linux() ->
     Res = os:cmd("cat /proc/meminfo"),
     case get_memory_usage_linux(Res, undef, undef) of
	{MemTotal, MemFree} ->
	    {MemTotal-MemFree, MemTotal};
	error ->
	    timer:sleep(1000),
	    get_memory_usage_linux()
     end.

get_memory_usage_linux(_Str, Tot, Free) when is_integer(Tot),
					     is_integer(Free) ->
     {Tot, Free};
get_memory_usage_linux("MemTotal:"++T, _Tot0, Free0) ->
     {ok, [N], Rest} = io_lib:fread("~d", T),
     Tot = N*1024,
     get_memory_usage_linux(skip_to_eol(Rest), Tot, Free0);
get_memory_usage_linux("MemFree:"++T, Tot0, _Free0) ->
     {ok, [N], Rest} = io_lib:fread("~d", T),
     Free = N*1024,
     get_memory_usage_linux(skip_to_eol(Rest), Tot0, Free);
get_memory_usage_linux("", _Tot0, _Free0) ->
     error;
get_memory_usage_linux(Str, Tot0, Free0) ->
     get_memory_usage_linux(skip_to_eol(Str), Tot0, Free0).
%-------------------------

Regards,

Serge

-- 
Serge Aleynikov
R&D Telecom, MIS, IDT Corp
Tel: +1 (973) 438-3436
Fax: +1 (973) 438-1464



More information about the erlang-questions mailing list