diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/vm_memory_monitor.erl | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index 91788caae8..02bd04991e 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -37,8 +37,6 @@ %% %% This module tries to warn Rabbit before such situations occur, so %% that it has a higher chance to avoid running out of memory. -%% -%% This code depends on Erlang os_mon application. -module(vm_memory_monitor). @@ -78,6 +76,7 @@ ('ignore' | {'error', any()} | {'ok', pid()})). -spec(update/0 :: () -> 'ok'). -spec(get_total_memory/0 :: () -> (non_neg_integer() | 'unknown')). +-spec(get_vm_limit/0 :: () -> (non_neg_integer() | 'unknown')). -spec(get_memory_limit/0 :: () -> (non_neg_integer() | 'undefined')). -spec(get_check_interval/0 :: () -> non_neg_integer()). -spec(set_check_interval/1 :: (non_neg_integer()) -> 'ok'). @@ -97,6 +96,9 @@ update() -> get_total_memory() -> get_total_memory(os:type()). +get_vm_limit() -> + get_vm_limit(os:type()). + get_check_interval() -> gen_server:call(?MODULE, get_check_interval, infinity). @@ -208,17 +210,26 @@ start_timer(Timeout) -> {ok, TRef} = timer:apply_interval(Timeout, ?MODULE, update, []), TRef. +%% According to http://msdn.microsoft.com/en-us/library/aa366778(VS.85).aspx +%% Windows has 2GB and 8TB of address space for 32 and 64 bit accordingly. +get_vm_limit({win32,_OSname}) -> + case erlang:system_info(wordsize) of + 4 -> 2*1024*1024*1024; %% 2 GB for 32 bits 2^31 + 8 -> 8*1024*1024*1024*1024 %% 8 TB for 64 bits 2^42 + end; + %% On a 32-bit machine, if you're using more than 2 gigs of RAM you're %% in big trouble anyway. -get_vm_limit() -> +get_vm_limit(_OsType) -> case erlang:system_info(wordsize) of - 4 -> 4294967296; %% 4 GB for 32 bits 2^32 - 8 -> 281474976710656 %% 256 TB for 64 bits 2^48 + 4 -> 4*1024*1024*1024; %% 4 GB for 32 bits 2^32 + 8 -> 256*1024*1024*1024*1024 %% 256 TB for 64 bits 2^48 %%http://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details end. get_mem_limit(MemFraction, TotalMemory) -> - lists:min([trunc(TotalMemory * MemFraction), get_vm_limit()]). + AvMem = lists:min([TotalMemory, get_vm_limit()]), + trunc(AvMem * MemFraction). %%---------------------------------------------------------------------------- %% Internal Helpers @@ -250,11 +261,14 @@ get_total_memory({unix,freebsd}) -> PageCount * PageSize; get_total_memory({win32,_OSname}) -> - [Result|_] = os_mon_sysinfo:get_mem_info(), - {ok, [_MemLoad, TotPhys, _AvailPhys, - _TotPage, _AvailPage, _TotV, _AvailV], _RestStr} = - io_lib:fread("~d~d~d~d~d~d~d", Result), - TotPhys; + %% Due to the Erlang print format bug, on Windows boxes the memory size is + %% broken. For example Windows 7 64 bit with 4Gigs of RAM we get negative + %% memory size: + %% > os_mon_sysinfo:get_mem_info(). + %% ["76 -1658880 1016913920 -1 -1021628416 2147352576 2134794240\n"] + %% Due to this bug, we don't actually know anything. Even if the number is + %% postive we can't be sure if it's correct. + unknown; get_total_memory({unix, linux}) -> File = read_proc_file("/proc/meminfo"), |
