diff options
| -rw-r--r-- | docs/rabbitmqctl.1.xml | 20 | ||||
| -rw-r--r-- | src/rabbit.erl | 1 | ||||
| -rw-r--r-- | src/vm_memory_monitor.erl | 46 |
3 files changed, 40 insertions, 27 deletions
diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml index c506ad87dd..a92a105674 100644 --- a/docs/rabbitmqctl.1.xml +++ b/docs/rabbitmqctl.1.xml @@ -1296,9 +1296,13 @@ <para> Displays broker status information such as the running applications on the current Erlang node, RabbitMQ and - Erlang versions, OS name and memory statistics. (See - the <command>cluster_status</command> command to find - out which nodes are clustered and running.) + Erlang versions, OS name and memory statistics. + In this context <varname>vm_memory_high_watermark</varname> + indicates to the fraction of memory at which flow control is + triggered. <varname>vm_memory_limit</varname> refers to the + absolute memory threshhold (in bytes) at which flow control + is triggered. (See the <command>cluster_status</command> + command to find out which nodes are clustered and running.) </para> <para role="example-prefix">For example:</para> <screen role="example">rabbitmqctl status</screen> @@ -1392,11 +1396,15 @@ </variablelist> <para> Sets the memory threshhold fraction at which memory-based flow control is - triggered, until the broker restarts. This command is intended for use in - systems that support hot-swappable RAM. The corresponding configuration + triggered, until the broker restarts. The corresponding configuration setting should also be changed when the effects of this command should survive a broker restart. Use the <command>status</command> command to - confirm the currently active threshhold. + confirm the currently active memory threshhold. + </para> + <para> + This command may also be used to update the total memory on systems that support + hot-swappable RAM. The total amount of RAM is queried and the supplied fraction + is used to determine the absolute threshhold. </para> <screen role="example">rabbitmqctl set_vm_memory_high_watermark 0.4</screen> <para role="example"> diff --git a/src/rabbit.erl b/src/rabbit.erl index 138693f584..fdebeaf859 100644 --- a/src/rabbit.erl +++ b/src/rabbit.erl @@ -237,6 +237,7 @@ status() -> {erlang_version, erlang:system_info(system_version)}, {vm_memory_high_watermark, vm_memory_monitor:get_vm_memory_high_watermark()}, + {vm_memory_limit, vm_memory_monitor:get_memory_limit()}, {memory, erlang:memory()}]. environment() -> diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index fb2fa267cb..bc673c01b5 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -40,6 +40,7 @@ -define(SERVER, ?MODULE). -define(DEFAULT_MEMORY_CHECK_INTERVAL, 1000). +-define(ONE_MB, 1048576). %% For an unknown OS, we assume that we have 1GB of memory. It'll be %% wrong. Scale by vm_memory_high_watermark in configuration to get a @@ -106,35 +107,21 @@ start_link(Args) -> gen_server:start_link({local, ?SERVER}, ?MODULE, [Args], []). init([MemFraction]) -> - TotalMemory = - case get_total_memory() of - unknown -> - error_logger:warning_msg( - "Unknown total memory size for your OS ~p. " - "Assuming memory size is ~pMB.~n", - [os:type(), trunc(?MEMORY_SIZE_FOR_UNKNOWN_OS/1048576)]), - ?MEMORY_SIZE_FOR_UNKNOWN_OS; - M -> M - end, - MemLimit = get_mem_limit(MemFraction, TotalMemory), - error_logger:info_msg("Memory limit set to ~pMB.~n", - [trunc(MemLimit/1048576)]), TRef = start_timer(?DEFAULT_MEMORY_CHECK_INTERVAL), - State = #state { total_memory = TotalMemory, - memory_limit = MemLimit, - timeout = ?DEFAULT_MEMORY_CHECK_INTERVAL, + State = #state { timeout = ?DEFAULT_MEMORY_CHECK_INTERVAL, timer = TRef, alarmed = false}, - {ok, internal_update(State)}. + {ok, internal_update(init_mem_state(State, MemFraction))}. handle_call(get_vm_memory_high_watermark, _From, State) -> {reply, State#state.memory_limit / State#state.total_memory, State}; handle_call({set_vm_memory_high_watermark, MemFraction}, _From, State) -> - MemLimit = get_mem_limit(MemFraction, State#state.total_memory), + State1 = init_mem_state(State, MemFraction), + MemLimit = get_mem_limit(MemFraction, State1#state.total_memory), error_logger:info_msg("Memory alarm changed to ~p, ~p bytes.~n", [MemFraction, MemLimit]), - {reply, ok, State#state{memory_limit = MemLimit}}; + {reply, ok, State1#state{memory_limit = MemLimit}}; handle_call(get_check_interval, _From, State) -> {reply, State#state.timeout, State}; @@ -168,6 +155,23 @@ code_change(_OldVsn, State, _Extra) -> %% Server Internals %%---------------------------------------------------------------------------- +init_mem_state(State, MemFraction) -> + TotalMemory = + case get_total_memory() of + unknown -> + error_logger:warning_msg( + "Unknown total memory size for your OS ~p. " + "Assuming memory size is ~pMB.~n", + [os:type(), trunc(?MEMORY_SIZE_FOR_UNKNOWN_OS/?ONE_MB)]), + ?MEMORY_SIZE_FOR_UNKNOWN_OS; + M -> M + end, + MemLim = get_mem_limit(MemFraction, TotalMemory), + error_logger:info_msg("Memory limit set to ~pMB of ~pMB total.~n", + [trunc(MemLim/?ONE_MB), trunc(TotalMemory/?ONE_MB)]), + State #state { total_memory = TotalMemory, + memory_limit = MemLim }. + internal_update(State = #state { memory_limit = MemLimit, alarmed = Alarmed}) -> MemUsed = erlang:memory(total), @@ -322,9 +326,9 @@ parse_line_sunos(Line) -> [Value1 | UnitsRest] = string:tokens(RHS, " "), Value2 = case UnitsRest of ["Gigabytes"] -> - list_to_integer(Value1) * 1024 * 1024 * 1024; + list_to_integer(Value1) * ?ONE_MB * 1024; ["Megabytes"] -> - list_to_integer(Value1) * 1024 * 1024; + list_to_integer(Value1) * ?ONE_MB; ["Kilobytes"] -> list_to_integer(Value1) * 1024; _ -> |
