Skip to content
This repository was archived by the owner on Nov 17, 2020. It is now read-only.

Commit 391858b

Browse files
Merge pull request #221 from rabbitmq/rabbitmq-server-1343
Optimise memory reporting to call less system memory reports.
2 parents 1f4daac + d7c4fcb commit 391858b

File tree

1 file changed

+33
-21
lines changed

1 file changed

+33
-21
lines changed

src/vm_memory_monitor.erl

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
-record(state, {total_memory,
4747
memory_limit,
48+
process_memory,
4849
memory_config_limit,
4950
timeout,
5051
timer,
@@ -69,7 +70,7 @@
6970
-spec get_memory_limit() -> non_neg_integer().
7071
-spec get_memory_use(bytes) -> {non_neg_integer(), float() | infinity};
7172
(ratio) -> float() | infinity.
72-
73+
-spec get_cached_process_memory_and_limit() -> {non_neg_integer(), non_neg_integer()}.
7374
%%----------------------------------------------------------------------------
7475
%% Public API
7576
%%----------------------------------------------------------------------------
@@ -109,16 +110,19 @@ set_vm_memory_high_watermark(Fraction) ->
109110
get_memory_limit() ->
110111
gen_server:call(?MODULE, get_memory_limit, infinity).
111112

113+
get_cached_process_memory_and_limit() ->
114+
gen_server:call(?MODULE, get_cached_process_memory_and_limit, infinity).
115+
112116
get_memory_use(bytes) ->
113-
MemoryLimit = get_memory_limit(),
114-
{get_process_memory(), case MemoryLimit > 0.0 of
115-
true -> MemoryLimit;
116-
false -> infinity
117-
end};
117+
{ProcessMemory, MemoryLimit} = get_cached_process_memory_and_limit(),
118+
{ProcessMemory, case MemoryLimit > 0.0 of
119+
true -> MemoryLimit;
120+
false -> infinity
121+
end};
118122
get_memory_use(ratio) ->
119-
MemoryLimit = get_memory_limit(),
123+
{ProcessMemory, MemoryLimit} = get_cached_process_memory_and_limit(),
120124
case MemoryLimit > 0.0 of
121-
true -> get_process_memory() / MemoryLimit;
125+
true -> ProcessMemory / MemoryLimit;
122126
false -> infinity
123127
end.
124128

@@ -225,7 +229,7 @@ start_link(MemFraction, AlarmSet, AlarmClear) ->
225229
[MemFraction, {AlarmSet, AlarmClear}], []).
226230

227231
init([MemFraction, AlarmFuns]) ->
228-
TRef = start_timer(?DEFAULT_MEMORY_CHECK_INTERVAL),
232+
TRef = erlang:send_after(?DEFAULT_MEMORY_CHECK_INTERVAL, self(), update),
229233
State = #state { timeout = ?DEFAULT_MEMORY_CHECK_INTERVAL,
230234
timer = TRef,
231235
alarmed = false,
@@ -243,20 +247,32 @@ handle_call(get_check_interval, _From, State) ->
243247
{reply, State#state.timeout, State};
244248

245249
handle_call({set_check_interval, Timeout}, _From, State) ->
246-
{ok, cancel} = timer:cancel(State#state.timer),
247-
{reply, ok, State#state{timeout = Timeout, timer = start_timer(Timeout)}};
250+
State1 = case erlang:cancel_timer(State#state.timer) of
251+
false ->
252+
State#state{timeout = Timeout};
253+
_ ->
254+
State#state{timeout = Timeout,
255+
timer = erlang:send_after(Timeout, self(), update)}
256+
end,
257+
{reply, ok, State1};
248258

249259
handle_call(get_memory_limit, _From, State) ->
250260
{reply, State#state.memory_limit, State};
251261

262+
handle_call(get_cached_process_memory_and_limit, _From, State) ->
263+
{reply, {State#state.process_memory, State#state.memory_limit}, State};
264+
252265
handle_call(_Request, _From, State) ->
253266
{noreply, State}.
254267

255268
handle_cast(_Request, State) ->
256269
{noreply, State}.
257270

258271
handle_info(update, State) ->
259-
{noreply, internal_update(State)};
272+
erlang:cancel_timer(State#state.timer),
273+
State1 = internal_update(State),
274+
TRef = erlang:send_after(State1#state.timeout, self(), update),
275+
{noreply, State1#state{ timer = TRef }};
260276

261277
handle_info(_Info, State) ->
262278
{noreply, State}.
@@ -365,26 +381,22 @@ parse_mem_limit(MemLimit) ->
365381
internal_update(State = #state { memory_limit = MemLimit,
366382
alarmed = Alarmed,
367383
alarm_funs = {AlarmSet, AlarmClear} }) ->
368-
MemUsed = get_process_memory(),
369-
NewAlarmed = MemUsed > MemLimit,
384+
ProcMem = get_process_memory(),
385+
NewAlarmed = ProcMem > MemLimit,
370386
case {Alarmed, NewAlarmed} of
371-
{false, true} -> emit_update_info(set, MemUsed, MemLimit),
387+
{false, true} -> emit_update_info(set, ProcMem, MemLimit),
372388
AlarmSet({{resource_limit, memory, node()}, []});
373-
{true, false} -> emit_update_info(clear, MemUsed, MemLimit),
389+
{true, false} -> emit_update_info(clear, ProcMem, MemLimit),
374390
AlarmClear({resource_limit, memory, node()});
375391
_ -> ok
376392
end,
377-
State #state {alarmed = NewAlarmed}.
393+
State #state {alarmed = NewAlarmed, process_memory = ProcMem}.
378394

379395
emit_update_info(AlarmState, MemUsed, MemLimit) ->
380396
rabbit_log:info(
381397
"vm_memory_high_watermark ~p. Memory used:~p allowed:~p~n",
382398
[AlarmState, MemUsed, MemLimit]).
383399

384-
start_timer(Timeout) ->
385-
{ok, TRef} = timer:send_interval(Timeout, update),
386-
TRef.
387-
388400
%% According to http://msdn.microsoft.com/en-us/library/aa366778(VS.85).aspx
389401
%% Windows has 2GB and 8TB of address space for 32 and 64 bit accordingly.
390402
get_vm_limit({win32,_OSname}) ->

0 commit comments

Comments
 (0)