[Erlang 0013]抓取Erlang进程运行时信息

简介:

     [Erlang 0012]Erlang Process input queue 一文我们提到使用erlang:process_info/1抓取进程运行时状态信息,有时我们需要把节点内所有的进程的信息都抓取下来,便于分析整个节点内进程的运行状态,特别是挑出一些异常的进程:比如有些进程的reduction值和其它进程相比大出好几个数量级,那这个进程需要好好检查一下了。

    下面的代码就是把当前节点内所有进程遍历一遍,把进程状态写入到文本里面:

process_infos() ->          
    filelib:ensure_dir("./log/"),
    File = "./log/processes_infos.log",
    {ok, Fd} = file:open(File, [write, raw, binary, append]), 
    Fun = fun(Pi) ->
                   Info = io_lib:format("=>~p \n\n",[Pi]),
                  case  filelib:is_file(File) of
                        true   ->   file:write(Fd, Info);
                        false  ->
                            file:close(Fd),
                            {ok, NewFd} = file:open(File, [write, raw, binary, append]),
                            file:write(NewFd, Info)
                     end,
                     timer:sleep(20)
                 end,
    [   Fun(erlang:process_info(P)) ||   P <- erlang:processes()].      
 
运行一下看看,我们还要学会读这些数据:
[{registered_name,rex},
   {current_function,{gen_server,loop,6}},
   {initial_call,{proc_lib,init_p,5}},
   {status,waiting},
   {message_queue_len,0},
   {messages,[]},
   {links,[<0.10.0>]},
   {dictionary,[{'$ancestors',[kernel_sup,<0.9.0>]},
                {'$initial_call',{rpc,init,1}}]},
   {trap_exit,true},
   {error_handler,error_handler},
   {priority,normal},
   {group_leader,<0.8.0>},
   {total_heap_size,28657},
   {heap_size,10946},
   {stack_size,9},
   {reductions,13905},
   {garbage_collection,[{min_bin_vheap_size,10946},
                        {min_heap_size,10946},
                        {fullsweep_after,65535},
                        {minor_gcs,2}]}, %%% erlang的垃圾回收是mark sweep方式。 major做全量的gc, minor就是不够内存的时候,缺多少就去回收下,力度比较小。
   {suspending,[]}]
 
这些字段的含义:
 
{current_function, {Module, Function, Args}}

当前进程调用的方法M F A

{dictionary, Dictionary}

当前进程的进程字典数据,调试过程中我们可以为进程添加一些特殊标记来识别进程

{garbage_collection, GCInfo}

GCInfo is a list which contains miscellaneous information about garbage collection for this process. The content of GCInfo may be changed without prior notice.

{group_leader, GroupLeader}

GroupLeader决定了最终的信息输出在什么地方,比如rpc会把远程执行的结果采集过来在当前shell显示,就用到这个GroupLeader

{heap_size, Size}

Size is the size in words of youngest heap generation of the process. This generation currently include the stack of the process. This information is highly implementation dependent, and may change if the implementation change.

{initial_call, {Module, Function, Arity}}

ModuleFunctionArity is the initial function call with which the process was spawned.

{links, Pids}

关联进程列表

{last_calls, false|Calls}

The value is false if call saving is not active for the process (see process_flag/3). If call saving is active, a list is returned, in which the last element is the most recent called.

{memory, Size}

Size is the size in bytes of the process. This includes call stack, heap and internal structures.

{message_binary, BinInfo}

BinInfo is a list containing miscellaneous information about binaries currently being referred to by the message area. This InfoTuple is only valid on an emulator using the hybrid heap type. This InfoTuple may be changed or removed without prior notice.

{message_queue_len, MessageQueueLen}

这就是上文中我们特别关注的消息队列的长度

{messages, MessageQueue}

堆积消息列表

{min_heap_size, MinHeapSize}

最小堆大小

{min_bin_vheap_size, MinBinVHeapSize}

进程最小二进制虚拟堆大小

{monitored_by, Pids}

当前进程的监控进程列表

{priority, Level}

进程优先级,通过 process_flag(priority, Level).设置

{reductions, Number}

这个参数是进程负载的粗略评估指标.常备缩写为REds

Reduction is an approximate measure of how much CPU time they have used.

 

这个是一个计数,是Erlang虚拟机用来调度进程的一个依据,保证公平调度。
比如某个进程执行一个函数,reduction就会增加,执行gc reduction会进行减少。

 已回复 4月 13日 作者: litaocheng

{registered_name, Atom}

进程注册的名称.

{stack_size, Size}

进程栈大小(单位是word)

{status, Status}

进程状态,有exitinggarbage_collectingwaiting (for a message), runningrunnable (ready to run, but another process is running), or suspended 

{total_heap_size, Size}

Size is the total size in words of all heap fragments of the process. This currently include the stack of the process.

{trap_exit, Boolean}

是否为系统进程,"Erlang系统进程"这样一个名字太容易产生误解了,本质上意味着什么呢?系统进程和普通进程唯一的区别就是可以把退出信号转换成为普通的消息.

 

 

 详情参见:http://www.erlang.org/doc/man/erlang.html#process_info-2

 

单个Erlang Process 占用多少内存?

An Erlang process is lightweight compared to operating systems threads and processes.

A newly spawned Erlang process uses 309 words of memory in the non-SMP emulator without HiPE support. (SMP support and HiPE support will both add to this size.) The size can be found out like this:

复制代码
Erlang (BEAM) emulator version 5.6 [async-threads:0] [kernel-poll:false]

Eshell V5.6  (abort with ^G)
1> Fun = fun() -> receive after infinity -> ok end end.
#Fun<...>
2> {_,Bytes} = process_info(spawn(Fun), memory).
{memory,1232}
3> Bytes div erlang:system_info(wordsize).
309
复制代码

The size includes 233 words for the heap area (which includes the stack). The garbage collector will increase the heap as needed.

 

Link:http://www.erlang.org/doc/efficiency_guide/processes.html

 

2014-2-28 10:58:48 重新做了上面的测试,看下结果:

 这个大小包含了233字的heap area(包含stack).GC会按照需求调整heap大小.
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Eshell V5.10.2  (abort with ^G)
1> Fun=fun() -> receive after infinity ->ok end end.
#Fun<erl_eval.20.80484245>
2> {_,Bytes}=process_info(spawn(Fun),memory).
{memory,2656}
3> Bytes div erlang:system_info(wordsize).
332
4>
4> erlang:system_info(wordsize).
8
5> process_info(spawn(Fun)).
[{current_function,{erlang,apply,2}},
{initial_call,{erlang,apply,2}},
{status,runnable},
{message_queue_len,0},
{messages,[]},
{links,[]},
{dictionary,[]},
{trap_exit, false },
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.26.0>},
{total_heap_size,233},
{heap_size,233},
{stack_size,0},
{reductions,0},
{garbage_collection,[{min_bin_vheap_size,46422},
                       {min_heap_size,233},
                       {fullsweep_after,65535},
                       {minor_gcs,0}]},
{suspending,[]}]
6>

  

启动的时候通过+h 选项或者在spawn的时候通过spawn_opt指定min_heap_size可以定制进程创建的heap初始值;如果一个进程需要的heap较大,那么一开始分配好比通过GC增长开销要小,还有一个好处是如果进程heap有空余,GC可能会收缩heap,而minsize配置会防止这种情况.
 
除了Refc Bin外,进程间的消息数据都是通过拷贝实现的,消息如果是发送到其它节点,首先会被转换为Erlang External Format 然后再投递到TCP/IP Socket.接收到信息的节点解码消息并移交信息到指定进程.
 
Erlang的字面常量数据(literals)会在constant pools维护,每一个模块被加载之后都有自己的pool(换句话说这个设计的粒度是模块级).如果常量数据被发送到其它进程或者存入ETS,就会触发拷贝.这样做的原因是:运行时系统要能跟踪都所有常量数据的引用计数以便能够unload包含常量数据的模块,如果模块被unload,其包含的常量数据会被拷贝到使用它的进程的heap空间.
  
共享部分数据(sub_terms)有些情况下不会保留:1.发送到其它进程,2.用做进程创建初始化函数 3.存入ETS表;
这里有一篇论文专门讨论这个话题,有兴趣的可以看下:
 
On Preserving Term Sharing in the Erlang Virtual Machine
 
注意由于考虑到对现有应用的影响,Erlang开发团队并没有计划把Preserving of sharing 做成默认的.

 


目录
相关文章
|
3月前
|
关系型数据库 MySQL
MySQL查看连接数和进程信息
这篇文章介绍了如何在MySQL中查看连接数和进程信息,包括当前打开的连接数量、历史成功建立连接的次数、连接错误次数、连接超时设置,以及如何查看和终止正在执行的连接进程。
703 10
|
4月前
|
Linux Python
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
75 2
|
1月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
98 1
|
3月前
|
Linux Shell
6-9|linux查询现在运行的进程
6-9|linux查询现在运行的进程
|
2月前
|
NoSQL Linux 程序员
进程管理与运行分析
进程管理与运行分析
27 0
|
3月前
|
Python
惊!Python进程间通信IPC,让你的程序秒变社交达人,信息畅通无阻
【9月更文挑战第13天】在编程的世界中,进程间通信(IPC)如同一场精彩的社交舞会,每个进程通过优雅的IPC机制交换信息,协同工作。本文将带你探索Python中的IPC奥秘,了解它是如何让程序实现无缝信息交流的。IPC如同隐形桥梁,连接各进程,使其跨越边界自由沟通。Python提供了多种IPC机制,如管道、队列、共享内存及套接字,适用于不同场景。通过一个简单的队列示例,我们将展示如何使用`multiprocessing.Queue`实现进程间通信,使程序如同社交达人般高效互动。掌握IPC,让你的程序在编程舞台上大放异彩。
29 3
|
4月前
|
数据采集 监控 API
如何监控一个程序的运行情况,然后视情况将进程杀死并重启
这篇文章介绍了如何使用Python的psutil和subprocess库监控程序运行情况,并在程序异常时自动重启,包括多进程通信和使用日志文件进行断点重续的方法。
|
3月前
|
缓存 运维 NoSQL
使用 psutil 获取硬件、网络以及进程信息
使用 psutil 获取硬件、网络以及进程信息
63 0
|
3月前
|
NoSQL
gdb中获取进程收到的最近一个信号的信息
gdb中获取进程收到的最近一个信号的信息
|
4月前
|
Java Windows
【Azure Developer】Windows中通过pslist命令查看到Java进程和线程信息,但为什么和代码中打印出来的进程号不一致呢?
【Azure Developer】Windows中通过pslist命令查看到Java进程和线程信息,但为什么和代码中打印出来的进程号不一致呢?