- 浏览: 101519 次
- 性别:
- 来自: 杭州
-
最新评论
-
johncan:
但是如果绑定错误,反而会有反效果,请问如何看是否绑定错误?是否 ...
erlang程序优化点的总结(持续更新) -
mahengyang:
如何使用mnesia:select/4分页查询%%对事务封装了 ...
mnesia监控项目 -
zjjxxl:
mysql代码高手,我们这里mysql5.6长时间运行内存过高 ...
innodb对B树游标的定位过程以及对“小于(等于)B树最小记录”的特殊处理 -
wqtn22:
是原创啊,霸爷mryufeng认证的,增加引用计数和减少引用计 ...
erlang NIF部分接口实现(三)持久资源 -
magicxiao:
enif_release_resource当引用计数为0的时候 ...
erlang NIF部分接口实现(三)持久资源
文章列表
线上有一台t4的机器,这些机器的cpu topo是经过伪造的,通过top命令可以看到4个核心:
top
Cpu0 : 0.3%us, 0.0%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.7%st
Cpu1 : 0.7%us, 0.3%sy, 0.0%ni, 98.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.3%st
Cpu2 : 0.3%us, 0.7%sy, 0.0%ni, 78.1%id, 0.0%wa, 0.0%hi, 0.0%si, 20.9%st
Cpu3 ...
mnesia在运行时提供了大量的统计量,对这些统计量进行监控,有助于正确使用mnesia,以及对mnesia进行调优,这些统计量包括:
代码版本R15B03
1.启动与运行时参数:
运行相关参数:
mnesia是否在运行中:mnesia:system_info (is_running)
信息输出级别:mnesia:system_info (debug)
是否使用数据存储目录:mnesia:system_info (use_dir)
数据存储目录位置:mnesia:system_info (directory)
初始schema位置:mnesia:system ...
我们在程序开发过程中,存在如下的一段代码:
F = fun () ->
Recs = mnesia:index_read(table, Index, indexfield),
NewRecs = some_ops_on(Recs),
mnesia:write(NewRecs)
end,
mnesia:transaction(F).
这段代码在运行时并发一直上不去,读者是否清楚其原因呢?
文章的末尾总结了一些mnesia的使用注意事项,对源码没有兴趣的读者可以直接看末尾。
仔细分析一下mnesia:index_read/3的工作过程, ...
转载请注明出处
注意,这里只是给出一个总结,具体性能需要根据实际环境和需要来确定
霸爷指出,新的erlang虚拟机有很多调优启动参数,今后现在这个方面深挖一下。
1. 进程标志设置:
消息和binary内存:erlang:process_flag(min_bin_vheap_size, 1024*1024),减少大量消息到达或处理过程中产生大量binary时的gc次数
堆内存:erlang:process_flag(min_heap_size, 1024*1024),减少处理过程中产生大量term,尤其是list时的gc次数
进程优先 ...
innodb对B树进行游标定位时,主要通过函数btr_cur_search_to_nth_level进行,该函数从根页开始向下层页迭代,直到指定的层级level,最终将B树游标定位在第一个大/小于(等于)tuple的位置,先不考虑页面latch、锁、自适应哈希索引、插入缓冲的影响,仅看B树游标定位:
UNIV_INTERN
void
btr_cur_search_to_nth_level(
/*========================*/
dict_index_t* index, /*!< in: index */
...
铁血的同学遇到这样一个问题,与之前4399同学遇到的问题类似,当初以为是erlang:ports/0的快照问题,仔细分析后发现另有玄机。
以下是问题描述:
>> 我使用的erlang版本是R15B03,进行socket处理的时候,如果在客户端到服务端有大概1000多个连接的时候(同时有较多的数据在发送),同时关闭所有客户端,
>> 这时在使用ports()查询出的端口中,有一些对其port_info/1返回的是undefined,
>> 并且这些undefined端口一样会占用端口数量,(出现这种情况的时候socket的控制进程确认已经都结束了)
...
在R15B01上,遇到一个gen_tcp/gen_udp:controlling_process(Port, self())导致的port泄露问题,下列链接详细的说明了产生问题的步骤:
https://github.com/erlang/otp/commit/944a57a11a79c5a9bb2f554c921e2e00e7d56c91
该问题在R15B03得到了修复,此处分析这个问题如下:
1> {ok,Port} = gen_udp:open(9000, [binary]).
{ok,#Port<0.581>}
2> i(0,31,0). ...
最近4399的同学遇到一个问题,以下是他的描述:
“用erlang:ports得出来的port列表里,很多port的port_info都是undefined,实际上这些ports应该都已经被关闭了,手动调用close去关闭这些port的话会抛出异常。”
首先重现他的场景:
在时刻t1调用erlang:ports()时可以得到erlang虚拟机在t1的所有port,在t1时刻之后的t2时刻,再次调用erlang:port_info()得到每个port的信息,两次调用间有一个时间差tv。
根据这个场景,有两种假设:
1.在时间差tv内,可能有一部分端口被关闭,导致t1时刻有效的por ...
NIF除了自身提供的功能外,还封装了一系列driver的功能,这些功能与操作系统平台紧密相关,主要包括:
系统信息,
操作系统线程及线程私有资源 ,条件变量、信号量、读写锁等,这些功能本身与erlang的进程体系无关,本身也是线程安全的,因此可以直接复用到NIF中,统一NIF的接口。
此处简单的分析一个操作系统线程创建的接口,其余的类似。
int enif_thread_create(char *name, ErlNifTid *tid, void* (*func)(void *),
void *args, ErlNifThreadOpts *opts) {
...
erlang NIF部分接口实现(四)消息发送
- 博客分类:
- erts
erlang中不能没有消息和异步过程,NIF也必须有此项能力,这个能力是通过enif_send实现的,它可以在NIF中向一个进程发送消息,但由于消息本身需要跨进程传递,消息的生命周期可能很长,而在erlang NIF部分接口实现(一)中可以看到,NIF每次调用所使用的ErlNifEnv结构是位于process_main函数的栈上的,由这个ErlNifEnv结构分配消息所占用的内存是不可能的,因此需要一个长期存在的ErlNifEnv结构来回收消息的内存,而ErlNifEnv结构是附着于一个进程的,同时也需要一个Process结构,产生分配内存的堆。
为了构建这个长期存在的ErlNifEnv结构, ...
erlang NIF部分接口实现(三)持久资源
- 博客分类:
- erts
持久资源是NIF中一类非常有用接口,可以把资源看成各种数据结构描述符,然后在各个模块间传递数据结构,从而使得写erlang程序像写c程序一样,弥补一些erlang程序在性能上的不足。
使用持久资源,需要首先创建持久资源类,这些工作可以在NIF被load时进行。
ErlNifResourceType*
enif_open_resource_type(ErlNifEnv* env,
const char* module_str,
const char* name_str,
ErlNifResourceDtor* dtor,
ErlNifResource ...
NIF的内存管理接口为enif_alloc/enif_free。
erl_nif.c
void* enif_alloc(size_t size)
{
return erts_alloc_fnf(ERTS_ALC_T_NIF, (Uint) size);
}
erl_alloc.h
ERTS_ALC_INLINE
void *erts_alloc_fnf(ErtsAlcType_t type, Uint size)
{
return (*erts_allctrs[ERTS_ALC_T2A(type)].alloc)(
ERTS_ALC_T2 ...
最近在项目中频繁用到erlang的NIF接口,以扩展erlang虚拟机的功能,同时又能提供较高的性能。
NIF(native implemented functions)从R14B开始支持,其功能在于,能够使得erlang module的功能通过c/c++实现。
erlang虚拟机有很多与外部进行功能交互的方式,如通过spawn_executable类型的port调用其它程序,port_driver,nif等,它们各有适应的场合:
spawn_executable类型的port会产生一个外部进程执行命令,不会干扰到erlang虚拟机本身,但是性能较低;
port_driver遵循erla ...
上文介绍了代码生成过程,成功的从erlang抽象码生成了erlang源文件,抽象码的替换步骤很少,这主要得益于模板文件pokemon_pb.erl的设计。这里将继续分析pokemon_pb.erl的执行过程,从中学习它的编程技巧。
编码过程:
pokemon_pb.erl
encode_pikachu(Record) when is_record(Record, pikachu) ->
encode(pikachu, Record).
encode(pikachu, Record) ->
iolist_to_binary(iolist(pikachu ...
上文介绍了protobuffs的语义分析过程,发现其收集了目标proto文件及其import文件的符号表,此处继续观察代码生成过程。
符号表的格式如下:
[
Message1 = {MessageName,
[
Field1 = {FieldId,
FieldRule(required/optional/repeated/repeated_packed...),
...