Erlang中的GC性能

fra*_*nco 2 erlang garbage-collection memory-management

我最近开始编写erlang编程,我想了解一些关于GC的内容.据我所知,每个进程的私有堆都有一个世代GC,而全局共享堆有一个引用计数GC.我想知道的是,无论如何还有:

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

有没有办法在运行erlang程序时使用代码或使用某些命令获取此类信息?

谢谢.

Ada*_*erg 9

  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,[]}]
    
    Run Code Online (Sandbox Code Playgroud)

    该过程的收集周期数量可在minor_gcs该部分的字段中找到garbage_collection.

  2. 按流程

    heap_size从上面的结果字段中可以获得进程的当前堆大小(单词,32位VM上的4个字节和64位VM上的8个字节).可以通过调用erlang:process_info(Pid, memory)例如{memory,34312}上述过程的返回来获得进程的总内存消耗.这包括调用堆栈,堆和内部结构.

    可以使用跟踪解除分配(和分配)erlang:trace/3.如果跟踪标志是garbage_collection您将在表单上收到消息{trace, Pid, gc_start, Info}{trace, Pid, gc_end, Info}.消息的Info字段gc_start包含诸如heap_size和之类的东西old_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}]
    
    Run Code Online (Sandbox Code Playgroud)

    可以获得垃圾收集统计数据,通过erlang:statistics(garbage_collection)它获得:

    > statistics(garbage_collection).
    {85,23961,0}
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    它们可以通过spawn选项进行控制,特别min_heap_size是为进程设置初始堆大小.

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

    您还可以通过+M...Erlang VM 的选项控制全局VM内存分配.这里描述标志.但是,这需要有关Erlang VM及其分配器内部的广泛知识,因此不应轻视它们.

  4. 这可以通过答案2中描述的跟踪获得.如果timestamp在跟踪时使用该选项,您将收到每个跟踪消息的时间戳,可用于计算总GC时间.

  5. 简答:不.

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

更多信息可以在效率指南的学术和历史问题过程部分找到.

正如Steve Vinoski所提到的,在运行时反省Erlang内存使用的最实用的方法是通过Recon库.