標籤:erlang 效能分析 etop eprof fprof
Etop
類似top命令,查看erlang進程佔用cpu、記憶體較高的進程
參數:
node atom erlang node
port integer The used port
accumulate boolean If true execution time is accumulated
lines integer Number of displayed processes
interval integer Display update interval in secs
sort runtime | reductions | memory | msg_q
output graphical | text
tracing on | off
setcookie string
使用舉例:
1. 找出cpu佔用最高的進程,圖形介面輸出,每10秒更新一次
> spawn(fun() -> etop:start([{interval,10}, {sort, runtime}]) end).> etop:stop().
2. 找出記憶體佔用較高進程, 輸出進程的數量為20,文本形式輸出
> spawn(fun() -> etop:start([{output, text}, {lines, 20}, {sort, memory}]) end).> etop:stop().
3. 查看遠程節點etop:
> erl -name [email protected] -hidden -s etop -output text -sort memory -lines 20 -node '[email protected]' -setcookie mycookie123
或者:
> erl -name [email protected] -hidden> etop:start([{node,'[email protected]'}, {setcookie, "mycookie123"}, {output, text}, {lines, 20}, {sort, memory}])
當然我們還可以使用rpc:call
> erl -name [email protected] -setcookie mycookie123 > rpc:call('[email protected]', etop, start, [{output, text}, {lines, 20}, {sort, memory}]).
eprof
假設我們使用etop查到了cpu佔用時間較多的進程id,那麼可以使用eprof進行進一步的分析.
基本用法:
> eprof:start().> eprof:profile([pid(x,x,x)]).> eprof:stop_profiling().> eprof:analyze().> eprof:stop().
或:
> eprof:start_profiling([regNames], {gen, call, 4}).> eprof:stop_profiling().> eprof:analyze().> eprof:stop().
regNames可以填寫進程的註冊名, {gen, call, 4}表示只記錄gen:call/4這個函數
analyze結果樣本:
****** Process <0.60.0> -- 100.00 % of profiled time *** FUNCTION CALLS % TIME [uS / CALLS]-------- ----- --- ---- [----------]gen:call/4 2 0.00 0 [ 0.00]gen:do_call/4 2 0.22 1 [ 0.50]gen_server:call/2 2 0.44 2 [ 1.00]dbutil:i_connect/1 2 0.66 3 [ 1.50]gen:call/3 2 0.66 3 [ 1.50]resource_pool:get/1 2 0.66 3 [ 1.50]mvar:modify/2 2 0.66 3 [ 1.50]gen_server:decode_msg/8 4 0.88 4 [ 1.00]erlang:monitor/2 2 0.88 4 [ 2.00]erlang:demonitor/2 2 1.33 6 [ 3.00]gen_server:handle_msg/5 4 1.55 7 [ 1.75]myserver:handle_call/3 4 1.77 8 [ 2.00]gen_server:loop/6 4 1.99 9 [ 2.25]erlang:send/3 2 3.76 17 [ 8.50]gen_server:reply/2 4 84.51 382 [ 95.50]
fprof
fprof類似eprof,但是會把詳細資料儲存到檔案中,方便資料統計分析。
只看某一函數的簡單調用方法:
1> fprof:apply(Module, fun, Args).2> fprof:profile().3> fprof:analyse().
實際上在執行的時候,fprof:apply/3前後會自動添加trace([start, ...]) 和 trace(stop).
完整的寫法是:
> fprof:trace([start, {file, "./fprof.trace"}, {procs, PidSpec}]). %% 或者可以trace多個Pid,[PidSpec]> fprof:trace(stop).> fprof:profile({file, "./fprof.trace"}).> fprof:analyse([{dest, "fprof.analysis"}, append, {sort,own}]). %% 詳細參數見: http://www.erlang.org/doc/man/fprof.html#analyse-2
結果樣本:
1> fprof:apply(lists, reverse, ["abcdef"])."fedcba"2> fprof:profile().Reading trace data...End of trace!ok3> fprof:analyse().Processing data...Creating output...%% Analysis results:{ analysis_options, [{callers, true}, {sort, acc}, {totals, false}, {details, true}]}.% CNT ACC OWN [{ totals, 3, 0.027, 0.027}]. %%%% CNT ACC OWN [{ "<0.33.0>", 3,undefined, 0.027}]. %%{[{undefined, 0, 0.027, 0.019}], { {fprof,apply_start_stop,4}, 0, 0.027, 0.019}, % [{{lists,reverse,1}, 1, 0.008, 0.005}, {suspend, 1, 0.000, 0.000}]}. {[{{fprof,apply_start_stop,4}, 1, 0.008, 0.005}], { {lists,reverse,1}, 1, 0.008, 0.005}, % [{{lists,reverse,2}, 1, 0.003, 0.003}]}. {[{{lists,reverse,1}, 1, 0.003, 0.003}], { {lists,reverse,2}, 1, 0.003, 0.003}, % [ ]}.{[ ], { undefined, 0, 0.000, 0.000}, % [{{fprof,apply_start_stop,4}, 0, 0.027, 0.019}]}. {[{{fprof,apply_start_stop,4}, 1, 0.000, 0.000}], { suspend, 1, 0.000, 0.000}, % [ ]}.Done!ok