erlang中大多数结构是list,许多操作也是通过遍历list来实现的,我们在大量list操作的同时同样会带来一个问题——内存可能会因为无限制的list耗尽,所以一般一个完善的erlang系统总是要带一个系统级别的监控工具,用于在特殊情况下使系统免于内存耗尽的崩溃。尽管我们可能会用很多操作系统的工具来监控每个用户进程的内存等信息,但是对于每一个erlang进程来说,这种工具是做不到的。
erlang中自带的系统监控工具是os_mon,这个application包括cpu_sup,disksup,memsup,os_sup。当我们启动os_mon这个application后,除了os_sup之外,其他都会启动。当系统某项指标达到指定警戒线之后,系统会通过alarm handler发送事件,我们可以根据事件类型做对应处理。
附一小段代码
start() ->
application:start(os_mon),
memsup:set_procmem_high_watermark(0.05),
alarm_handler:add_alarm_handler(?MODULE).
stop() ->
alarm_handler:delete_alarm_handler(?MODULE),
application:stop(os_mon).
init([]) ->
{ok, state}.
handle_event({set_alarm, {process_memory_high_watermark, Pid}}, State) ->
?ERR(system_log, "~w", [Pid]),
F = fun() ->
{dictionary, Dict} = erlang:process_info(Pid, dictionary),
%%各类进程在异常情况下的退出处理,玩家进程:直接持久化玩家信息后kill掉
case lists:keyfind('$initial_call', 1, Dict) of
{_, [player | _]} ->
playerAssist:savePlayerAll(mytime:timestamp(), true, false),
erlang:exit(Pid, kill);
_ ->
ignore
end
end,
erlang:spawn(F),
{ok, State};