From 31a1942b61b7ba6392b6f83f3cbe5e94b3f5541a Mon Sep 17 00:00:00 2001 From: Shawn <506895667@qq.com> Date: Mon, 9 Aug 2021 09:28:50 +0800 Subject: [PATCH] fix(force_shutdown): cannot suicide if the process hangs up --- src/emqx_alarm_handler.erl | 2 +- src/emqx_misc.erl | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/emqx_alarm_handler.erl b/src/emqx_alarm_handler.erl index a69913afd..44186de60 100644 --- a/src/emqx_alarm_handler.erl +++ b/src/emqx_alarm_handler.erl @@ -61,7 +61,7 @@ handle_event({set_alarm, {system_memory_high_watermark, []}}, State) -> {ok, State}; handle_event({set_alarm, {process_memory_high_watermark, Pid}}, State) -> - emqx_alarm:activate(high_process_memory_usage, #{pid => Pid, + emqx_alarm:activate(high_process_memory_usage, #{pid => list_to_binary(pid_to_list(Pid)), high_watermark => emqx_os_mon:get_procmem_high_watermark()}), {ok, State}; diff --git a/src/emqx_misc.erl b/src/emqx_misc.erl index 04af5f72c..75db4227f 100644 --- a/src/emqx_misc.erl +++ b/src/emqx_misc.erl @@ -52,6 +52,8 @@ , hexstr2bin/1 ]). +-define(OOM_FACTOR, 1.25). + %% @doc Parse v4 or v6 string format address to tuple. %% `Host' itself is returned if it's not an ip string. maybe_parse_ip(Host) -> @@ -216,12 +218,26 @@ do_check_oom([{Val, Max, Reason}|Rest]) -> tune_heap_size(#{max_heap_size := MaxHeapSize}) -> %% If set to zero, the limit is disabled. - erlang:process_flag(max_heap_size, #{size => MaxHeapSize, - kill => false, + erlang:process_flag(max_heap_size, #{size => must_kill_heap_size(MaxHeapSize), + kill => true, error_logger => true }); tune_heap_size(undefined) -> ok. +%% We multiply the size with factor ?OOM_FACTOR, to give the +%% process a chance to suicide by `check_oom/1` +must_kill_heap_size(Size) -> + MaxAllowedSize = case erlang:system_info(wordsize) of + 8 -> % arch_64 + (1 bsl 59) - 1; + 4 -> % arch_32 + (1 bsl 27) - 1 + end, + case ceil(Size * ?OOM_FACTOR) of + Size0 when Size0 >= MaxAllowedSize -> MaxAllowedSize; + Size0 -> Size0 + end. + -spec(proc_name(atom(), pos_integer()) -> atom()). proc_name(Mod, Id) -> list_to_atom(lists:concat([Mod, "_", Id])).