erlang 调优工具

转自 http://blog.csdn.net/huang1196/article/details/38660325

 

 

类似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秒更新一次

 

 
  1. > spawn(fun() -> etop:start([{interval,10}, {sort, runtime}]) end).  
  2. > etop:stop().  

 

 

2. 找出内存占用较高进程, 输出进程的数量为20,文本形式输出

 

 
  1. > spawn(fun() -> etop:start([{output, text}, {lines, 20},  {sort, memory}]) end).  
  2. > etop:stop().  

 

 

3. 查看远程节点etop:

 


  1. > erl -name abc@192.168.17.102 -hidden -s etop -output text -sort memory -lines 20 -node 'test@192.168.17.102' -setcookie mycookie123  

 

 

或者:

 
  1. > erl -name abc@192.168.17.102 -hidden  
  2. > etop:start([{node,'test@192.168.17.102'}, {setcookie, "mycookie123"}, {output, text}, {lines, 20},  {sort, memory}])  

 

rpc:call 

 
  1. > erl -name abc@192.168.17.102 -setcookie mycookie123   
  2. > rpc:call('test@192.168.17.102', etop, start, [[{output, text}, {lines, 20},  {sort, memory}]]).  

 

eprof

假设我们使用etop查到了cpu占用时间较多的进程id,那么可以使用eprof进行进一步的分析.

基本用法:

 

 
  1. > eprof:start().  
  2. > eprof:profile([pid(x,x,x)]).  
  3. > eprof:stop_profiling().  
  4. > eprof:analyze().  
  5. > eprof:stop().  

 

 

或:

 
  1. > eprof:start_profiling([regNames], {gen, call, 4}).  
  2. > eprof:stop_profiling().  
  3. > eprof:analyze().  
  4. > eprof:stop().  

 

regNames可以填写进程的注册名, {gen, call, 4}表示只记录gen:call/4这个函数

 

analyze结果示例:

 

 
  1. ****** Process <0.60.0>    -- 100.00 % of profiled time ***   
  2. FUNCTION                 CALLS      %  TIME  [uS / CALLS]  
  3. --------                 -----    ---  ----  [----------]  
  4. gen:call/4                   2   0.00     0  [      0.00]  
  5. gen:do_call/4                2   0.22     1  [      0.50]  
  6. gen_server:call/2            2   0.44     2  [      1.00]  
  7. dbutil:i_connect/1           2   0.66     3  [      1.50]  
  8. gen:call/3                   2   0.66     3  [      1.50]  
  9. resource_pool:get/1          2   0.66     3  [      1.50]  
  10. mvar:modify/2                2   0.66     3  [      1.50]  
  11. gen_server:decode_msg/8      4   0.88     4  [      1.00]  
  12. erlang:monitor/2             2   0.88     4  [      2.00]  
  13. erlang:demonitor/2           2   1.33     6  [      3.00]  
  14. gen_server:handle_msg/5      4   1.55     7  [      1.75]  
  15. myserver:handle_call/3       4   1.77     8  [      2.00]  
  16. gen_server:loop/6            4   1.99     9  [      2.25]  
  17. erlang:send/3                2   3.76    17  [      8.50]  
  18. 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).

 

完整的写法是:

 
  1. > fprof:trace([start, {file, "./fprof.trace"}, {procs, PidSpec}]).  %% 或者可以trace多个Pid,[PidSpec]  
  2. > fprof:trace(stop).  
  3. > fprof:profile({file, "./fprof.trace"}).  
  4. > fprof:analyse([{dest, "fprof.analysis"},{sort,own}]).  %% 详细参数见: http://www.erlang.org/doc/man/fprof.html#analyse-2  

 

结果示例:

 

 
  1. 1> fprof:apply(lists, reverse, ["abcdef"]).  
  2. "fedcba"  
  3. 2> fprof:profile().  
  4. Reading trace data...  
  5.   
  6. End of trace!  
  7. ok  
  8. 3> fprof:analyse().  
  9. Processing data...  
  10. Creating output...  
  11. %% Analysis results:  
  12. {  analysis_options,  
  13.  [{callers, true},  
  14.   {sort, acc},  
  15.   {totals, false},  
  16.   {details, true}]}.  
  17.   
  18. %                                               CNT       ACC       OWN          
  19. [{ totals,                                        3,    0.027,    0.027}].  %%% CNT是trace过程中函数调用的总数,ACC是整个trace的时间,OWN为函数执行时间  
  20.   
  21.   
  22. %                                               CNT       ACC       OWN          
  23. [{ "<0.33.0>",                                    3,undefined,    0.027}].   %%  
  24.   
  25. {[{undefined,                                     0,    0.027,    0.019}],       
  26.  { {fprof,apply_start_stop,4},                    0,    0.027,    0.019},     %  
  27.  [{{lists,reverse,1},                             1,    0.008,    0.005},        
  28.   {suspend,                                       1,    0.000,    0.000}]}.      
  29.   
  30. {[{{fprof,apply_start_stop,4},                    1,    0.008,    0.005}],       
  31.  { {lists,reverse,1},                             1,    0.008,    0.005},     %  
  32.  [{{lists,reverse,2},                             1,    0.003,    0.003}]}.      
  33.   
  34. {[{{lists,reverse,1},                             1,    0.003,    0.003}],       
  35.  { {lists,reverse,2},                             1,    0.003,    0.003},     %  
  36.  [ ]}.  
  37.   
  38. {[ ],  
  39.  { undefined,                                     0,    0.000,    0.000},     %  
  40.  [{{fprof,apply_start_stop,4},                    0,    0.027,    0.019}]}.      
  41.   
  42. {[{{fprof,apply_start_stop,4},                    1,    0.000,    0.000}],       
  43.  { suspend,                                       1,    0.000,    0.000},     %  
  44.  [ ]}.  
  45.   
  46.   
  47. Done!  
  48. ok  

 

%是一种标记,每一个“段落”中,%表示被调用的函数主体,%以上为调用它的函数,%以下为它调用的函数。“段落”中的CNT列表示被调用次数,Acc表示包括%之上的函数在内所花费的时间,own表示不包括%之上的函数所用的时间。

suspend表示进程挂起。

也可以将fprof这类工具卸载想监控的代码前后。

 

cprof

用于统计一个函数中的每个函数的调用次数。相较于eprof和fprof,cprof对性能影响很小,官方说大约10%

使用举例(引自官网)

 

1> cprof:start(),R=calendar:day_of_the_week(1896,4,27),cprof:pause(),R.
1
2> cprof:analyse(calendar).
{calendar,9,
          [{{calendar,df,2},1},
           {{calendar,dm,1},1},
           {{calendar,dy,1},1},
           {{calendar,last_day_of_the_month1,2},1},
           {{calendar,last_day_of_the_month,2},1},
           {{calendar,is_leap_year1,1},1},
           {{calendar,is_leap_year,1},1},
           {{calendar,day_of_the_week,3},1},
           {{calendar,date_to_gregorian_days,3},1}]}
3> cprof:stop().
3271

 

该示例表明day_of_the_week这个函数需要调用9个函数完成计算。

同样cprof可以嵌入代码中。

 

 

Webtool

webtool:start().  %% 默认端口8888, http://localhost:8888/

 

appmon:start(). %% 查看application树

 

pman:start().  %%监控进程

 

tv:start().  %% ets & mnesia

 

toolbar:start().  %% 包含了上面几个

 

转载于:https://www.cnblogs.com/nzg55555/p/8253738.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值