优化

  1. 通过erlang:process_info(PID, reductions).粗略评估进程的负载,如果值相对其他进程很大的话,负载会很高。
  2. 【不建议使用】通过spawn_opt/4来设置垃圾回收,erlang:system_info(fullsweep_after),可以使用erl -env ERL_FULLSWEEP_AFTER 0来加快垃圾回收,这个值可以设置为10~20。
  3. 垃圾回收是以进程为单位,垃圾回收的时候会导致进程挂起,每一个进程都只有一小部分活跃数据(live data),所以垃圾回收将会是一个很快的操作。
  4. 垃圾回收可以强制执行erlang:garbage_collect(PID),但是不建议使用。
  5. HiPE(High Performance Erlang) 在运算上会快2-3倍。
  6. 节点联通

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    %% 连接节点
    net_kernel:connect_node('test@localhost').
    %% 限定指定节点可以联通
    net_kernnel:allow(Nodes).
    %% 联通节点
    net_adm:ping('test@localhost').
    %% 主动断开节点
    [net_kernel:disconnect(X) || X <- nodes() -- [List_of_wanted_nodes]].
    %% 在rpc:call时,会自动节点联通
    %% 可以设置取消自动联通
    erl -kernel dist_auto_connect never
  7. foo() > bar:foo() > (Mod:Func()F()) > apply(Mod, Func, Args),匿名函数和apply/3在性能上是比较差的,但是在一般的编程中,这些差异可以忽略。

  8. 进程字典非常的快,但是打破了变量不变的原则,因此在书中都不建议使用,但是确实很快,比ets快一个数量级。但是这个测试也应该存在问题:ets是进程实现的,进程内部和进程之间的操作比较是否不太合理呢?
  9. 进程间数据共享的几种方式:
    • 独立进程(gen_server:call(PID, {get, test})
    • ETS
    • application(application:get(APP, test)
    • mochiglobal模块(动态编译,没有看)
  10. 内存泄露排查
    erlang中的内存泄露有两类,一类是进程内部逻辑,一类是没有正常销毁进程:
    进程内部的通过erlang:process_info(PID, memory)按照memory占用大小排序,获得最占用内存的进程。
    进程间通过shell的i()获得没有正常销毁的进程PID,然后erlang:process_info(PID)分析。