diff options
author | Matthew Sackman <matthew@lshift.net> | 2009-10-28 16:35:46 +0000 |
---|---|---|
committer | Matthew Sackman <matthew@lshift.net> | 2009-10-28 16:35:46 +0000 |
commit | 6ad777707b679edd5d58edc5ac3e5e811ff86975 (patch) | |
tree | 6ca6dd5d273922a68b9915e9e37469420dc0db76 /src/vm_memory_monitor.erl | |
parent | df5a328a797154e5cdec87cfbf409e8320d8a7b3 (diff) | |
download | rabbitmq-server-6ad777707b679edd5d58edc5ac3e5e811ff86975.tar.gz |
More cosmetics and reorganisations
Diffstat (limited to 'src/vm_memory_monitor.erl')
-rw-r--r-- | src/vm_memory_monitor.erl | 150 |
1 files changed, 79 insertions, 71 deletions
diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index 7d291f38..b4b8122b 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -52,7 +52,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). --export([update/0, get_total_memory/1, +-export([update/0, get_total_memory/0, get_check_interval/0, set_check_interval/1, get_vm_memory_high_watermark/0, set_vm_memory_high_watermark/1]). @@ -81,7 +81,7 @@ start_link(Args) -> init([MemFraction]) -> TotalMemory = - case get_total_memory(os:type()) of + case get_total_memory() of unknown -> rabbit_log:info("Unknown total memory size for your OS ~p. " "Assuming memory size is ~p bytes.~n", @@ -90,7 +90,7 @@ init([MemFraction]) -> M -> M end, MemLimit = get_mem_limit(MemFraction, TotalMemory), - rabbit_log:info("Memory limit set to ~pMiB.~n", + rabbit_log:info("Memory limit set to ~pMB.~n", [trunc(MemLimit/1048576)]), TRef = start_timer(?DEFAULT_MEMORY_CHECK_INTERVAL), State = #state { total_memory = TotalMemory, @@ -141,6 +141,65 @@ code_change(_OldVsn, State, _Extra) -> update() -> gen_server2:cast(?SERVER, update). +get_total_memory() -> + get_total_memory(os:type()). + +get_check_interval() -> + gen_server2:call(?MODULE, get_check_interval). + +set_check_interval(Fraction) -> + gen_server2:call(?MODULE, {set_check_interval, Fraction}). + +get_vm_memory_high_watermark() -> + gen_server2:call(?MODULE, get_vm_memory_high_watermark). + +set_vm_memory_high_watermark(Fraction) -> + gen_server2:call(?MODULE, {set_vm_memory_high_watermark, Fraction}). + +%%---------------------------------------------------------------------------- +%% Server Internals +%%---------------------------------------------------------------------------- + +internal_update(State = #state { memory_limit = MemLimit, + alarmed = Alarmed}) -> + MemUsed = erlang:memory(total), + NewAlarmed = MemUsed > MemLimit, + case {Alarmed, NewAlarmed} of + {false, true} -> + emit_update_info(set, MemUsed, MemLimit), + alarm_handler:set_alarm({vm_memory_high_watermark, []}); + {true, false} -> + emit_update_info(clear, MemUsed, MemLimit), + alarm_handler:clear_alarm(vm_memory_high_watermark); + _ -> + ok + end, + State #state {alarmed = NewAlarmed}. + +emit_update_info(State, MemUsed, MemLimit) -> + rabbit_log:info("vm_memory_high_watermark ~p. Memory used:~p allowed:~p~n", + [State, MemUsed, MemLimit]). + +start_timer(Timeout) -> + {ok, TRef} = timer:apply_interval(Timeout, ?MODULE, update, []), + TRef. + +%% On a 32-bit machine, if you're using more than 2 gigs of RAM you're +%% in big trouble anyway. +get_vm_limit() -> + case erlang:system_info(wordsize) of + 4 -> 2147483648; %% 2 GB for 32 bits 2^31 + 8 -> 140737488355328 %% 128 TB for 64 bits 2^47 + %% 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()]). + +%%---------------------------------------------------------------------------- +%% Internal Helpers +%%---------------------------------------------------------------------------- + %% get_total_memory(OS) -> Total %% Windows and Freebsd code based on: memsup:get_memory_usage/1 %% Original code was part of OTP and released under "Erlang Public @@ -193,22 +252,6 @@ get_total_memory({unix, sunos}) -> get_total_memory(_OsType) -> unknown. -get_check_interval() -> - gen_server2:call(?MODULE, get_check_interval). - -set_check_interval(Fraction) -> - gen_server2:call(?MODULE, {set_check_interval, Fraction}). - -get_vm_memory_high_watermark() -> - gen_server2:call(?MODULE, get_vm_memory_high_watermark). - -set_vm_memory_high_watermark(Fraction) -> - gen_server2:call(?MODULE, {set_vm_memory_high_watermark, Fraction}). - -%%---------------------------------------------------------------------------- -%% Internal Helpers -%%---------------------------------------------------------------------------- - %% A line looks like "Foo bar: 123456." parse_line_mach(Line) -> [Name, RHS | _Rest] = string:tokens(Line, ":"), @@ -222,26 +265,6 @@ parse_line_mach(Line) -> {list_to_atom(Name), list_to_integer(Value)} end. -freebsd_sysctl(Def) -> - list_to_integer(os:cmd("/sbin/sysctl -n " ++ Def) -- "\n"). - -%% file:read_file does not work on files in /proc as it seems to get -%% the size of the file first and then read that many bytes. But files -%% in /proc always have length 0, we just have to read until we get -%% eof. -read_proc_file(File) -> - {ok, IoDevice} = file:open(File, [read, raw]), - Res = read_proc_file(IoDevice, []), - file:close(IoDevice), - lists:flatten(lists:reverse(Res)). - --define(BUFFER_SIZE, 1024). -read_proc_file(IoDevice, Acc) -> - case file:read(IoDevice, ?BUFFER_SIZE) of - {ok, Res} -> read_proc_file(IoDevice, [Res | Acc]); - eof -> Acc - end. - %% A line looks like "FooBar: 123456 kB" parse_line_linux(Line) -> [Name, RHS | _Rest] = string:tokens(Line, ":"), @@ -271,37 +294,22 @@ parse_line_sunos(Line) -> [Name] -> {list_to_atom(Name), none} 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() -> - case erlang:system_info(wordsize) of - 4 -> 2*1024*1024*1024; % 2 GiB for 32 bits - 8 -> 64*1024*1024*1024*1024 % 64 TiB for 64 bits - end. - -get_mem_limit(MemFraction, TotalMemory) -> - lists:min([trunc(TotalMemory * MemFraction), get_vm_limit()]). - -start_timer(Timeout) -> - {ok, TRef} = timer:apply_interval(Timeout, ?MODULE, update, []), - TRef. +freebsd_sysctl(Def) -> + list_to_integer(os:cmd("/sbin/sysctl -n " ++ Def) -- "\n"). -emit_update_info(State, MemUsed, MemLimit) -> - rabbit_log:info("vm_memory_high_watermark ~p. Memory used:~p allowed:~p~n", - [State, MemUsed, MemLimit]). +%% file:read_file does not work on files in /proc as it seems to get +%% the size of the file first and then read that many bytes. But files +%% in /proc always have length 0, we just have to read until we get +%% eof. +read_proc_file(File) -> + {ok, IoDevice} = file:open(File, [read, raw]), + Res = read_proc_file(IoDevice, []), + file:close(IoDevice), + lists:flatten(lists:reverse(Res)). -internal_update(State = #state { memory_limit = MemLimit, - alarmed = Alarmed}) -> - MemUsed = erlang:memory(total), - NewAlarmed = MemUsed > MemLimit, - case {Alarmed, NewAlarmed} of - {false, true} -> - emit_update_info(set, MemUsed, MemLimit), - alarm_handler:set_alarm({vm_memory_high_watermark, []}); - {true, false} -> - emit_update_info(clear, MemUsed, MemLimit), - alarm_handler:clear_alarm(vm_memory_high_watermark); - _ -> - ok - end, - State #state {alarmed = NewAlarmed}. +-define(BUFFER_SIZE, 1024). +read_proc_file(IoDevice, Acc) -> + case file:read(IoDevice, ?BUFFER_SIZE) of + {ok, Res} -> read_proc_file(IoDevice, [Res | Acc]); + eof -> Acc + end. |