Erlang中的GC性能 [英] GC performance in Erlang

查看:126
本文介绍了Erlang中的GC性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始对erlang进行编程,关于GC我需要了解一些内容. 据我了解,每个进程的专用堆都有一个世代GC,全局共享堆有一个引用计数的GC. 我想知道的是,是否有得到的东西:

  1. 收集周期数是多少?
  2. 在全局级别或进程级别分配和释放了多少个字节?
  3. 什么是私有堆,共享堆的大小是多少?我们可以将其定义为GC参数吗?
  4. 收集垃圾需要多长时间?需要的时间百分比?
  5. 是否可以在没有GC的情况下运行程序?

运行erlang程序时,是否可以通过代码或使用某些命令来获取此类信息?

谢谢.

解决方案

  1. 要获取单个进程的信息,可以调用erlang:process_info(Pid). (从Erlang 18.0开始)这将产生以下字段:

     > erlang:process_info(self()).
    [{current_function,{erl_eval,do_apply,6}},
     {initial_call,{erlang,apply,2}},
     {status,running},
     {message_queue_len,0},
     {messages,[]},
     {links,[<0.27.0>]},
     {dictionary,[]},
     {trap_exit,false},
     {error_handler,error_handler},
     {priority,normal},
     {group_leader,<0.26.0>},
     {total_heap_size,4184},
     {heap_size,2586},
     {stack_size,24},
     {reductions,3707},
     {garbage_collection,[{min_bin_vheap_size,46422},
                          {min_heap_size,233},
                          {fullsweep_after,65535},
                          {minor_gcs,7}]},
     {suspending,[]}]
     

    该过程的收集周期数在garbage_collection部分下的minor_gcs字段中.

  2. 每个进程

    该进程的当前堆大小在上述结果的字段heap_size中可用(换句话说,在32位VM上为4字节,在64位VM上为8字节).可以通过调用erlang:process_info(Pid, memory)来获取该过程的总内存消耗,对于上述过程,该erlang:process_info(Pid, memory)返回例如{memory,34312}.这包括调用堆栈,堆和内部结构.

    解除分配(和分配)可以使用 erlang:trace/3 .如果跟踪标志为garbage_collection,您将收到{trace, Pid, gc_start, Info}{trace, Pid, gc_end, Info}格式的消息. gc_start消息的Info字段包含诸如heap_sizeold_heap_size之类的内容.

    每个系统

    可以通过 erlang:memory/0 :

     > erlang:memory().
    [{total,15023008},
     {processes,4215272},
     {processes_used,4215048},
     {system,10807736},
     {atom,202481},
     {atom_used,187597},
     {binary,325816},
     {code,4575293},
     {ets,234816}]
     

    可以通过 erlang:statistics(garbage_collection) 获取垃圾收集统计信息会产生:

     > statistics(garbage_collection).
    {85,23961,0}
     

    (从Erlang 18.0开始)第一个字段是VM执行的垃圾收集总数,第二个字段是回收的单词总数.

  3. 进程的堆大小在上面的进程信息的字段total_heap_size(所有堆碎片和堆栈)和heap_size(最年轻的堆生成大小)下提供.

    可以通过生成选项(特别是min_heap_size设置进程的初始堆大小.

    要为所有进程设置它,可以调用erlang:system_flag(min_heap_size, MinHeapSize).

    您还可以通过+M...选项控制Erlang VM的全局VM内存分配.在此处中描述这些标志.但是,这需要对Erlang VM及其分配器的内部知识有广泛的了解,使用它们时不应掉以轻心.

  4. 这可以通过答案2中描述的跟踪来获得.如果在跟踪时使用选项timestamp,则会收到带有每个跟踪消息的时间戳记,可用于计算总GC时间. /p>

  5. 简短答案:否.

    长答案:也许吧.您可以控制初始堆大小(通过min_heap_size),该大小将影响第一次进行垃圾收集的时间.您还可以使用fullsweep_after选项控制何时执行全扫描.

更多信息,请参见学术和历史问题过程部分.

在运行时内省Erlang内存使用的最实用方法是通过 Recon库,如提到了史蒂夫·维诺斯基.

I've started programming erlang recently and there are a few things I want to understand regarding GC. As far as I understand there is a generational GC for the private heap of each process and a reference counting GC for the global shared heap. What I would like to know is if there is anyway to get:

  1. How many number of collection cycles?
  2. How many bytes are allocated and deallocated, on a global level or process level?
  3. What are the private heaps, and shared heap sizes? And can we define this as a GC parameter?
  4. How long does it take to collect garbage? The % of time needed?
  5. Is there a way to run a program without GC?

Is there a way to get this kind of information, either with code or using some command when I run an erlang program?

Thanks.

解决方案

  1. To get information for a single process, you can call erlang:process_info(Pid). This will yield (as of Erlang 18.0) the following fields:

    > erlang:process_info(self()).
    [{current_function,{erl_eval,do_apply,6}},
     {initial_call,{erlang,apply,2}},
     {status,running},
     {message_queue_len,0},
     {messages,[]},
     {links,[<0.27.0>]},
     {dictionary,[]},
     {trap_exit,false},
     {error_handler,error_handler},
     {priority,normal},
     {group_leader,<0.26.0>},
     {total_heap_size,4184},
     {heap_size,2586},
     {stack_size,24},
     {reductions,3707},
     {garbage_collection,[{min_bin_vheap_size,46422},
                          {min_heap_size,233},
                          {fullsweep_after,65535},
                          {minor_gcs,7}]},
     {suspending,[]}]
    

    The number of collection cycles for the process is available in the field minor_gcs under the section garbage_collection.

  2. Per Process

    The current heap size for the process is available in the field heap_size from the results above (in words, 4 bytes on a 32-bit VM and 8 bytes on a 64-bit VM). The total memory consumption of the process can be obtained by calling erlang:process_info(Pid, memory) which returns for example {memory,34312} for the above process. This includes call stack, heap and internal structures.

    Deallocations (and allocations) can be traced using erlang:trace/3. If the trace flag is garbage_collection you will received messages on the form {trace, Pid, gc_start, Info} and {trace, Pid, gc_end, Info}. The Info field of the gc_start message contains such things as heap_size and old_heap_size.

    Per System

    Top level statistics of the system can be obtained by erlang:memory/0:

    > erlang:memory().
    [{total,15023008},
     {processes,4215272},
     {processes_used,4215048},
     {system,10807736},
     {atom,202481},
     {atom_used,187597},
     {binary,325816},
     {code,4575293},
     {ets,234816}]
    

    Garbage collection statistics can be obtained via erlang:statistics(garbage_collection) which yields:

    > statistics(garbage_collection).
    {85,23961,0}
    

    Where (as of Erlang 18.0) the first field is the total number of garbage collections performed by the VM and the second field is the total number of words reclaimed.

  3. The heap sizes for a process are available under the fields total_heap_size (all heap fragments and stack) and heap_size (the size of the youngest heap generation) from the process info above.

    They can be controlled via spawn options, specifically min_heap_size which sets the initial heap size for a process.

    To set it for all process, erlang:system_flag(min_heap_size, MinHeapSize) can be called.

    You can also control global VM memory allocation via the +M... options to the Erlang VM. The flags are described here. However, this requires extensive knowledge about the internals of the Erlang VM and its allocators and using them should not be taken lightly.

  4. This can be obtained via the tracing described in answer 2. If you use the option timestamp when tracing, you will receive a timestamp with each trace message that can be used to calculate the total GC time.

  5. Short answer: no.

    Long answer: Maybe. You can control the initial heap size (via min_heap_size) which will affect when garbage collection will occur the first time. You can also control when a full sweep will be performed with the fullsweep_after option.

More information can be found in the Academic and Historical Questions and Processes section of the Efficiency Guide.

The most practical way of introspecting Erlang memory usage at runtime is via the Recon library, as Steve Vinoski mentioned.

这篇关于Erlang中的GC性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆