45
45
46
46
-record (state , {total_memory ,
47
47
memory_limit ,
48
+ process_memory ,
48
49
memory_config_limit ,
49
50
timeout ,
50
51
timer ,
69
70
-spec get_memory_limit () -> non_neg_integer ().
70
71
-spec get_memory_use (bytes ) -> {non_neg_integer (), float () | infinity };
71
72
(ratio ) -> float () | infinity .
72
-
73
+ - spec get_cached_process_memory_and_limit () -> { non_neg_integer (), non_neg_integer ()}.
73
74
% %----------------------------------------------------------------------------
74
75
% % Public API
75
76
% %----------------------------------------------------------------------------
@@ -109,16 +110,19 @@ set_vm_memory_high_watermark(Fraction) ->
109
110
get_memory_limit () ->
110
111
gen_server :call (? MODULE , get_memory_limit , infinity ).
111
112
113
+ get_cached_process_memory_and_limit () ->
114
+ gen_server :call (? MODULE , get_cached_process_memory_and_limit , infinity ).
115
+
112
116
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 };
118
122
get_memory_use (ratio ) ->
119
- MemoryLimit = get_memory_limit (),
123
+ { ProcessMemory , MemoryLimit } = get_cached_process_memory_and_limit (),
120
124
case MemoryLimit > 0.0 of
121
- true -> get_process_memory () / MemoryLimit ;
125
+ true -> ProcessMemory / MemoryLimit ;
122
126
false -> infinity
123
127
end .
124
128
@@ -225,7 +229,7 @@ start_link(MemFraction, AlarmSet, AlarmClear) ->
225
229
[MemFraction , {AlarmSet , AlarmClear }], []).
226
230
227
231
init ([MemFraction , AlarmFuns ]) ->
228
- TRef = start_timer (? DEFAULT_MEMORY_CHECK_INTERVAL ),
232
+ TRef = erlang : send_after (? DEFAULT_MEMORY_CHECK_INTERVAL , self (), update ),
229
233
State = # state { timeout = ? DEFAULT_MEMORY_CHECK_INTERVAL ,
230
234
timer = TRef ,
231
235
alarmed = false ,
@@ -243,20 +247,32 @@ handle_call(get_check_interval, _From, State) ->
243
247
{reply , State # state .timeout , State };
244
248
245
249
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 };
248
258
249
259
handle_call (get_memory_limit , _From , State ) ->
250
260
{reply , State # state .memory_limit , State };
251
261
262
+ handle_call (get_cached_process_memory_and_limit , _From , State ) ->
263
+ {reply , {State # state .process_memory , State # state .memory_limit }, State };
264
+
252
265
handle_call (_Request , _From , State ) ->
253
266
{noreply , State }.
254
267
255
268
handle_cast (_Request , State ) ->
256
269
{noreply , State }.
257
270
258
271
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 }};
260
276
261
277
handle_info (_Info , State ) ->
262
278
{noreply , State }.
@@ -365,26 +381,22 @@ parse_mem_limit(MemLimit) ->
365
381
internal_update (State = # state { memory_limit = MemLimit ,
366
382
alarmed = Alarmed ,
367
383
alarm_funs = {AlarmSet , AlarmClear } }) ->
368
- MemUsed = get_process_memory (),
369
- NewAlarmed = MemUsed > MemLimit ,
384
+ ProcMem = get_process_memory (),
385
+ NewAlarmed = ProcMem > MemLimit ,
370
386
case {Alarmed , NewAlarmed } of
371
- {false , true } -> emit_update_info (set , MemUsed , MemLimit ),
387
+ {false , true } -> emit_update_info (set , ProcMem , MemLimit ),
372
388
AlarmSet ({{resource_limit , memory , node ()}, []});
373
- {true , false } -> emit_update_info (clear , MemUsed , MemLimit ),
389
+ {true , false } -> emit_update_info (clear , ProcMem , MemLimit ),
374
390
AlarmClear ({resource_limit , memory , node ()});
375
391
_ -> ok
376
392
end ,
377
- State # state {alarmed = NewAlarmed }.
393
+ State # state {alarmed = NewAlarmed , process_memory = ProcMem }.
378
394
379
395
emit_update_info (AlarmState , MemUsed , MemLimit ) ->
380
396
rabbit_log :info (
381
397
" vm_memory_high_watermark ~p . Memory used:~p allowed:~p~n " ,
382
398
[AlarmState , MemUsed , MemLimit ]).
383
399
384
- start_timer (Timeout ) ->
385
- {ok , TRef } = timer :send_interval (Timeout , update ),
386
- TRef .
387
-
388
400
% % According to http://msdn.microsoft.com/en-us/library/aa366778(VS.85).aspx
389
401
% % Windows has 2GB and 8TB of address space for 32 and 64 bit accordingly.
390
402
get_vm_limit ({win32 ,_OSname }) ->
0 commit comments