Erlang Tips

转载请注明:来自http://blog.csdn.net/skyman_2001

一、ets
1. ets效率建议(原文出处:http://pro.it165.net/html/201110/950.html)

(1) ets表的底层是由哈希表实现的,不过有序集例外,它是由平衡二叉树实现的。 所以不管是插入还是查找,集合的效率要比有序集高.

(2) 可重复袋要比袋的效率要高, 因为袋要和原来的记录比较是否有相同的记录已经插入. 如果一份大数据,相同的记录越多,袋的效率就越慢.

(3) 一张ets表是由创建它的进程所拥有, 当此进程调用ets:delete或者进程挂了的时候, 表会被删除.

(4) 一般情况下, 插入一个元组到一张ets表中, 所有代表这个元组的结构都会被从进程的栈和堆中,复制到ets表中; 当查找一条记录时, 结果元组从ets表中复制到进程的栈和堆中。

但是大型二进制(large binaries) 数据却不是这样! 它们被存入自已所拥有的堆区域(off-heap area)中。这个区域可以被多个进程,ets表,和独立二进制数据所共享。它由引用计数的垃圾回收策略管理, 这个策略会跟踪到底有多少个进程/ets表/二进制数据引用了这个大型二进制数据. 如果引用数为0的话, 此大型二进制数据就会被垃圾回收掉.

看起来很和复杂, 实际结论就是: 两进程间发消息用大型二进制数据消耗很低, 往ets表插入元组用二进制数据也很划算。我们应该尽可能采用二进制数据来实现字符串或无类型的大数据块.

2. 原文出处:http://www.cnblogs.com/me-sa/archive/2011/08/11/erlang0007.html

(1) ETS查询时间是常量,例外是如果使用ordered_set查询时间与logN成正比(N为存储的数据量)
(2) ETS 存储数据的格式是Tuple
(3) ETS Table由进程创建,进程销毁ETS Table也随着销毁,在使用Shell做ETS实验的时候要注意一下,Table的拥有关系可以give_away 转交给其它进程
(4) 一个Erlang节点的ETS表的数量是有限制的,默认是1400个表,在启动erlang节点之前修改 ERL_MAX_ETS_TABLES参数可以修改这个限制
(5) 目前版本,insert和lookup操作都会导致对象副本的创建,insert和lookup时间对于set bag duplicate_bag都是常量值与表大小无关.
(6) 并发控制:所有针对一个对象的更新都被保证是原子的、隔离的:修改要么全部成功要么失败。也没有其它的中间结果被其它的进程使用。有些方法可以在处理多个对象的时候保证这种原子性和隔离性。
在数据库术语中隔离级别被称作序列化,就好像所有隔离的操作一个接一个严格按照顺序执行。
(7) 在遍历过程中,可以使用safe_fixtable来保证遍历过程中不出现错误,所有数据项只被访问一遍.用到逐一遍历的场景就很少,使用safe_fixtable的情景就更少。不过这个机制是非常有用的,
还记得在.net中版本中很麻烦的一件事情就是遍历在线玩家用户列表.由于玩家登录退出的变化,这里的异常几乎是不可避免的.select match内部实现的时候都会使用safe_fixtable

3. 选用建议(原文出处:http://erlangdisplay.iteye.com/blog/374167)
元素个数0~100个,选list

元素个数 100~10000个,选ets

元素个数10000个以上,选gb_tree

4. 查看节点的当前ets表数量

length(ets:all()).

5. http://erlang.2086793.n4.nabble.com/Is-ets-insert-2-with-multiple-objects-isolated-with-respect-to-concurrent-readers-td2116353.html

the implementation (R13B01) of ets:insert/2
takes a table lock if the second argument is a non-empty
list in order to ensure atomicity.

6. http://erlang.2086793.n4.nabble.com/Preventing-a-race-condition-when-using-dets-ets-td2105529.html

As from R12B-2, one call to ets:update_counter/3 can update several
integer-counters within the same ets-object.

ets:insert(Tab,{key,Done,LeftToDo}).
:
ets:update_counter(Tab,key,[{2,1},{3,-1}]).

7. ETS bag performance characteristics: http://erlang.org/pipermail/erlang-questions/2011-October/061706.html

All ETS tables, except ordered_set, are hash tables with separate
chaining to resolve collisions.

On average constant time for insert/lookup/removal of scattered keys. A
bag with lots of identical keys
may give bad performance as that will result in linear searches between
objects with the same key
(and others that happen to hash to the same bucket).

ordered_set is implented as a binary AVL tree.


二、Shell

1. 在shell中打开Erlang工具集界面:toolbar:start();

2. 显示全部数据:rp();

3. regs() -- information about registered processes
nregs() -- information about all registered processes

4. 查看VM资源信息:按Ctrl+C,然后按i,显示的内容见下:

void info(int to, void *to_arg)
{
erts_memory(&to, to_arg, NULL, THE_NON_VALUE);
atom_info(to, to_arg);
module_info(to, to_arg);
export_info(to, to_arg);
register_info(to, to_arg);
erts_fun_info(to, to_arg);
erts_node_table_info(to, to_arg);
erts_dist_table_info(to, to_arg);
erts_allocated_areas(&to, to_arg, NULL);
erts_allocator_info(to, to_arg);
}

5. 产生crashdump(运行期快照):先按Ctrl+C,再按大写A。摘自:http://blog.yufeng.info/archives/1847

用kill -USR1 erlpid或kill -s SIGUSR1 erlpid杀掉erlpid进程,erlang会生成crashdump


三、如何自己生成pid?

方法1:Pid = list_to_pid("<0.36.0>").

方法2:Pid = pid(0, 36, 0).

四、

让Erlang服务器后台运行:1. -noshell (该参数关闭终端,但依然不会后台运行,有输出时会直接打印到当前屏幕;2. -noinput 禁止终端下的输入 3. -hidden 隐藏运行;4. -detached 后台方式运行。最好用的是-detached,等效于同时带-noshell和-noinput参数(用ps -ef|grep beam查看便知)。

五、

如何连接detached模式的erlang节点?方法: 通过远程shell JCL登录,1.启动一个erlang节点:erl -name bar@192.168.1.103 -setcookie abc 2. Ctrl+G进入shell JCL,然后远程连接detached模式的erlang:--> r 'foo@192.168.1.103' --> c Eshell V5.7.1 (abort with ^G) (foo@192.168.1.103)1> 详见:http://cryolite.iteye.com/blog/383927

六、

如果shell一直在刷信息,如何终止shell?方法:按Ctrl+G,然后按q退出shell。另外,按h可以显示帮助信息。

七、调度

1. http://blog.yufeng.info/archives/336

port是和进程一样公平调度的. 进程是按照reductions为单位调度的, port是把发送的字节数折合成reductions. 所以如果一个进程发送大量的tcp数据 那么这个进程不是一直会得到执行的. 运行期会强制停止一段时间, 让其他port有机会执行的。

八、binary & bitstring

1. binary和bitstring的区别:位数能被8整除的bitstring是binary。

九、erlang beam执行是加载的流程(ERTS; code-server; dynamically loading of code):
http://erlang.2086793.n4.nabble.com/erlang-questions-ERTS-code-server-dynamically-loading-of-code-td2091745.html

When a function can not be found, a function in the module error_handler
is called in the context of the process wishing to execute the
non-existing function. The code in the error_handler communicated with
the code_server process (implemeneted in code) which implements the
dynamic code loading. Read those modules and you will understand.



十、Supervisor

Supervisor的最大重启次数是针对该supervisor下的所有被监控进程重启次数的总和,允许的次数是包含最大次数的。

十一、进程相关

1. gen_server进程(proc_lib初始化)比直接使用spawn创建的进程会多出一些信息,比如注册名,进程的父进程信息,初始化调用的函数等等:
{dictionary,[{'$ancestors',[<0.34.0>]},
{'$initial_call',{application_master,init,4}}]}

详见:http://www.cnblogs.com/me-sa/archive/2011/11/22/erlang0017.html

2. 获取进程状态:

get_status(Name) -> Status
get_status(Name, Timeout) -> Status

Types:
Name = name()
Timeout = timeout()
Status =
{status, Pid :: pid(), {module, Module :: module()}, [SItem]}
SItem = (PDict :: [{Key :: term(), Value :: term()}])
| (SysState :: running | suspended)
| (Parent :: pid())
| (Dbg :: dbg_opt())
| (Misc :: term())

Gets the status of the process.

The value of Misc varies for different types of processes. For example, a gen_server process returns the callback module's state, and a gen_fsm process returns information such as its current state name. Callback modules for gen_server and gen_fsm can also customise the value of Misc by exporting aformat_status/2 function that contributes module-specific information; see gen_server:format_status/2 and gen_fsm:format_status/2 for more details.

这样就不需要每个gen_server进程自己写获得State的接口了。

3. 获取进程调用堆栈

erlang:process_info(Pid, current_stacktrace). 格式和erlang:get_stacktrace/0相同,不过erlang:get_stacktrace/0只有在出异常时才能返回调用堆栈,如果无异常,则返回[](不过执行有些erlang库自带函数即使没异常erlang:get_stacktrace/0也会返回调用堆栈,比如执行erl_parse:parse_term())
erlang:process_info(Pid, backtrace). 二进制格式,信息更详细,除了调用堆栈,还包括指令指针等信息
erlang:process_display(Pid, backtrace). 和erlang:process_info(Pid, backtrace)一样,只不过打印格式更方便阅读(shell对应的命令是bt(Pid))


erlang:process_display(Pid, backtrace)和erlang:process_info(Pid, current_function)组合使用可以查看当前进程的函数调用细节。

十二、基础相关

1. atom加单引号和不加单引号是一样的:

5> B1=a.
a
6> B2='a'.
a
7> B1=:=B2.
true

十三、debug相关

1. Debugger工具的详细图文教程:http://www.erlang.org/doc/apps/debugger/debugger_chapter.html

尤其是条件断点

2. Appmon工具对调试进程间相互关系很有帮助

十四、Dialyzer

dialyzer plt building:

$ dialyzer --build_plt \
--output_plt .dialyzer-R14B01.plt \
--apps kernel stdlib sasl erts ssl \
tools os_mon runtime_tools crypto \
inets xmerl webtool snmp public_key \
mnesia eunit syntax_tools compiler \
./deps/*/ebin

dialyzer analysis:

$ dialyzer ./ebin --plt .dialyzer-R14B01.plt \
-Wunmatched_returns \
-Werror_handling \
-Wrace_conditions \
-Wbehaviours \
-Wunderspecs

原文地址:http://bob.ippoli.to/erl_testing_2011/

十五、compile相关

1. erlang编译流程

Source code -> Core Erlang -> Virtual BEAM code -> BEAM bytecode -> Threaded code

c(mod, to_core) c(mod, 'S') erts_debug:df(mod [,fun])

.hrl, .erl .core .S .dis


c(mod, 'S')也可以erlc +”‘S’” mod.erl

参考文章:

(1) A Peek Inside the Erlang Compiler: http://prog21.dadgum.com/127.html

(2) Erlang源码汇编格式: http://blog.yufeng.info/archives/498

(3) 实验Erlang语法对应的opcode 让你对erlang理解更深: http://blog.yufeng.info/archives/34

(4) Erlang Opcodes and their meaning: http://stackoverflow.com/questions/13397434/erlang-opcodes-and-their-meaning
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值